using System.Data; using System.Reflection; namespace Pilz.Collections.SimpleHistory; /// /// Represent some Object States and Actions. /// public class HistoryPoint { /// /// Represents the Name of this History Point /// /// public string Name { get; set; } = string.Empty; /// /// A List of Object States and Actions. /// /// public List Entries { get; } = []; /// /// Some data can be refered on this HistoryPoint. Don't know, in some situations this can be helpful. /// public readonly object? Tag = null; public bool HasEntries() where T : ObjectBase { return Entries.Where(n => n is T).Any(); } internal void Undo() { foreach (var s in Entries.OrderBy(n => n.UndoPriority)) { switch (s) { case ObjectState state: state.Patch(); break; case ObjectAction action: action.Undo(); break; } } } internal void Redo() { foreach (var s in Entries.OrderBy(n => n.RedoPriority)) { switch (s) { case ObjectState state: state.Patch(); break; case ObjectAction action: action.Redo(); break; } } } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify which members to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, MemberWhiteList whiteList) { return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify which members to exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, MemberBlackList blackList) { return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, params string[] memberName) { return FromObject(obj, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default); else return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, params string[] memberName) { return FromObject(obj, membersToStore, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default); else return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// The Binding Flags that the members should have. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, BindingFlags flags, params string[] memberName) { return FromObject(obj, flags, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// The Binding Flags that the members should have. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, BindingFlags flags, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags); else return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName) { return FromObject(obj, flags, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags); else return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify which members to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, MemberWhiteList whiteList) { return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify which members to exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, MemberBlackList blackList) { return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, params string[] memberName) { return FromObject(obj, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default); else return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, params string[] memberName) { return FromObject(obj, membersToStore, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default); else return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// The Binding Flags that the members should have. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, BindingFlags flags, params string[] memberName) { return FromObject(obj, flags, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// The Binding Flags that the members should have. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, BindingFlags flags, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags); else return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// The member names to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName) { return FromObject(obj, flags, true, memberName); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// If true, the memberName-Array has member names that should be included. /// The member names to include/exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName) { if (isWhiteList) return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags); else return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// A History Point with Object States. public static HistoryPoint FromObject(object obj) { return FromObject([obj], ObjectValueType.None, default(object), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore) { return FromObject([obj], membersToStore, default(object), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// Specify which members to include. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList) { return FromObject([obj], membersToStore, (object)whiteList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// Specify which members to exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList) { return FromObject([obj], membersToStore, (object)blackList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, BindingFlags flags) { return FromObject([obj], ObjectValueType.None, default(object), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags) { return FromObject([obj], membersToStore, default(object), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// Specify which members to include. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags) { return FromObject([obj], membersToStore, (object)whiteList, flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The object that should be included. /// Specify what member types to include. /// Specify which members to exclude. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags) { return FromObject([obj], membersToStore, (object)blackList, flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs) { return FromObject(objs, ObjectValueType.None, default(object), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore) { return FromObject(objs, membersToStore, default(object), BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// Specify which members to include. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList) { return FromObject(objs, membersToStore, (object)whiteList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// Specify which members to exclude. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList) { return FromObject(objs, membersToStore, (object)blackList, BindingFlags.Default); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, BindingFlags flags) { return FromObject(objs, ObjectValueType.None, default(object), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, BindingFlags flags) { return FromObject(objs, membersToStore, default(object), flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// Specify which members to include. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags) { return FromObject(objs, membersToStore, (object)whiteList, flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// Specify which members to exclude. /// The Binding Flags that the members should have. /// A History Point with Object States. public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags) { return FromObject(objs, membersToStore, (object)blackList, flags); } /// /// Creates an History Point with Object States automaticly from input. /// /// The objects that should be included. /// Specify what member types to include. /// Specify which members to include. /// The Binding Flags that the members should have. /// A History Point with Object States. private static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, object? whiteOrBlackList, BindingFlags flags) { var hp = new HistoryPoint(); whiteOrBlackList ??= new MemberBlackList(); var isWhiteList = whiteOrBlackList is MemberWhiteList; if (flags == BindingFlags.Default) flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; if (membersToStore == ObjectValueType.None) membersToStore = ObjectValueType.Field | ObjectValueType.Property; foreach (var obj in objs) { if ((membersToStore & ObjectValueType.Field) == ObjectValueType.Field) { foreach (var fi in obj.GetType().GetFields(flags)) { var contains = ((List)whiteOrBlackList).Contains(fi.Name); if (isWhiteList ? contains : !contains) { var os = new ObjectState { Object = obj, MemberName = fi.Name, MemberType = ObjectValueType.Field, MemberFlags = flags, ValueToPatch = fi.GetValue(obj) }; hp.Entries.Add(os); } } } if ((membersToStore & ObjectValueType.Property) == ObjectValueType.Property) { foreach (var pi in obj.GetType().GetProperties(flags)) { var contains = ((List)whiteOrBlackList).Contains(pi.Name); if (isWhiteList ? contains : !contains) { var os = new ObjectState { Object = obj, MemberName = pi.Name, MemberType = ObjectValueType.Property, MemberFlags = flags, ValueToPatch = pi.GetValue(obj) }; hp.Entries.Add(os); } } } } return hp; } /// /// Combines some History Points to one. /// /// An array of History Points to combine. /// One History Point that contains all Data of inputted History Points. public static HistoryPoint Concat(params HistoryPoint[] hps) { return Concat(null, hps); } /// /// Combines some History Points to one. /// /// An array of History Points to combine. /// The new name for the History Point after concating. /// One History Point that contains all Data of inputted History Points. public static HistoryPoint Concat(string? newName, params HistoryPoint[] hps) { var hp = new HistoryPoint(); foreach (var _hp in hps) hp.Entries.AddRange(_hp.Entries); if (newName != null) hp.Name = newName; else hp.Name = hps.FirstOrDefault()?.Name ?? string.Empty; return hp; } }