using System.Collections.Generic; using System.Data; using System.Linq; using global::System.Reflection; using Microsoft.VisualBasic.CompilerServices; 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; } = ""; /// /// A List of Object States and Actions. /// /// public List Entries { get; private set; } = new List(); /// /// 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).Count() > 0; } internal void Undo() { foreach (ObjectBase s in Entries.OrderBy(n => n.UndoPriority)) { if (s is ObjectState) { ((ObjectState)s).Patch(); } else if (s is ObjectAction) { ((ObjectAction)s).Undo(); } } } internal void Redo() { foreach (ObjectBase s in Entries.OrderBy(n => n.RedoPriority)) { if (s is ObjectState) { ((ObjectState)s).Patch(); } else if (s is ObjectAction) { ((ObjectAction)s).Redo(); } } } /// /// 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(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, ObjectValueType.None, new MemberWhiteList(memberName), BindingFlags.Default); } else { return FromObject(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, membersToStore, new MemberWhiteList(memberName), BindingFlags.Default); } else { return FromObject(new[] { obj }, membersToStore, 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(new[] { obj }, ObjectValueType.None, new MemberWhiteList(memberName), flags); } else { return FromObject(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, membersToStore, new MemberWhiteList(memberName), flags); } else { return FromObject(new[] { obj }, membersToStore, 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(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, ObjectValueType.None, new MemberWhiteList(memberName), BindingFlags.Default); } else { return FromObject(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, membersToStore, new MemberWhiteList(memberName), BindingFlags.Default); } else { return FromObject(new[] { obj }, membersToStore, 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(new[] { obj }, ObjectValueType.None, new MemberWhiteList(memberName), flags); } else { return FromObject(new[] { obj }, ObjectValueType.None, 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(new[] { obj }, membersToStore, new MemberWhiteList(memberName), flags); } else { return FromObject(new[] { obj }, membersToStore, 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(new[] { obj }, ObjectValueType.None, (object)null, 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(new[] { obj }, membersToStore, (object)null, 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(new[] { obj }, membersToStore, 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(new[] { obj }, membersToStore, 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(new[] { obj }, ObjectValueType.None, (object)null, 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(new[] { obj }, membersToStore, (object)null, 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(new[] { obj }, membersToStore, 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(new[] { obj }, membersToStore, 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, (object)null, 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, (object)null, 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, 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, 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, (object)null, 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, (object)null, 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, 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, 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(); if (whiteOrBlackList is null) whiteOrBlackList = new MemberBlackList(); bool 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 (object obj in objs) { if ((membersToStore & ObjectValueType.Field) == ObjectValueType.Field) { foreach (FieldInfo fi in obj.GetType().GetFields(flags)) { bool contains = Conversions.ToBoolean(((List)whiteOrBlackList).Contains(fi.Name)); if (isWhiteList ? contains : !contains) { var os = new ObjectState(); os.Object = obj; os.MemberName = fi.Name; os.MemberType = ObjectValueType.Field; os.MemberFlags = flags; os.ValueToPatch = fi.GetValue(obj); hp.Entries.Add(os); } } } if ((membersToStore & ObjectValueType.Property) == ObjectValueType.Property) { foreach (PropertyInfo pi in obj.GetType().GetProperties(flags)) { bool contains = Conversions.ToBoolean(((List)whiteOrBlackList).Contains(pi.Name)); if (isWhiteList ? contains : !contains) { var os = new ObjectState(); os.Object = obj; os.MemberName = pi.Name; os.MemberType = ObjectValueType.Property; os.MemberFlags = flags; os.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(hps.FirstOrDefault()?.Name, hps); } /// /// 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(string newName, params HistoryPoint[] hps) { var hp = new HistoryPoint(); foreach (HistoryPoint _hp in hps) hp.Entries.AddRange(_hp.Entries); return hp; } } }