Browse Source

Improving speed of ToObject by using cached objects in DatabaseSchema and decreasing some initialisation

Kenric Nugteren 1 year ago
parent
commit
665ea1c85a

+ 5 - 11
InABox.Core/BaseObject.cs

@@ -63,12 +63,12 @@ namespace InABox.Core
 
             UserProperties = new UserProperties();
             //UserProperties.ParentType = this.GetType();
+            DatabaseSchema.InitializeObject(this);
             UserProperties.OnPropertyChanged += (o, n, b, a) =>
             {
                 if (IsObserving())
                     OnPropertyChanged(n, b, a);
             };
-            DatabaseSchema.InitializeObject(this);
             
             CheckSequence();
         }
@@ -95,15 +95,9 @@ namespace InABox.Core
         public void SetObserving(bool active)
         {
             bApplyingChanges = true;
-            //UserProperties.ParentType = this.GetType();
             _observing = active;
-            foreach (var oo in CoreUtils.GetChildren<IBaseObject>(this))
+            foreach (var oo in DatabaseSchema.GetSubObjects(this))
                 oo.SetObserving(active);
-            /*UserProperties.OnPropertyChanged += (o, n, b, a) =>
-            {
-                if (_observing)
-                    OnPropertyChanged(n, b, a);
-            };*/
             bApplyingChanges = false;
         }
 
@@ -153,7 +147,7 @@ namespace InABox.Core
             if (OriginalValues.Count > 0)
                 return true;
 
-            foreach (var oo in CoreUtils.GetChildren<IBaseObject>(this))
+            foreach (var oo in DatabaseSchema.GetSubObjects(this))
                 if (oo.IsChanged())
                     return true;
 
@@ -264,7 +258,7 @@ namespace InABox.Core
             bChanged = false;
 
 
-            foreach (var oo in CoreUtils.GetChildren<IBaseObject>(this)) oo.CancelChanges();
+            foreach (var oo in DatabaseSchema.GetSubObjects(this)) oo.CancelChanges();
 
             SetObserving(bObs);
             bApplyingChanges = false;
@@ -279,7 +273,7 @@ namespace InABox.Core
 
             bChanged = false;
 
-            foreach (var oo in CoreUtils.GetChildren<IBaseObject>(this))
+            foreach (var oo in DatabaseSchema.GetSubObjects(this))
                 oo.CommitChanges();
 
             bApplyingChanges = false;

+ 1 - 1
InABox.Core/CoreTable/CoreRow.cs

@@ -92,7 +92,7 @@ namespace InABox.Core
             for (var i = 0; i < Table.Columns.Count; i++)
             {
                 var column = Table.Columns[i].ColumnName;
-                var value = this[column];
+                var value = Values[i];
                 try
                 {
                     if (obj.LoadedColumns.Add(column) || overrideExisting)

+ 1 - 4
InABox.Core/CoreUtils.cs

@@ -1157,7 +1157,6 @@ namespace InABox.Core
         /// <returns>A list of the objects found</returns>
         public static IEnumerable<T> GetChildren<T>(object parent)
         {
-            var children = new List<T>();
             var props = PropertyList(
                 parent.GetType(),
                 x => typeof(T).IsAssignableFrom(x.PropertyType)
@@ -1166,10 +1165,8 @@ namespace InABox.Core
             {
                 var child = (T)prop.GetValue(parent);
                 if (child != null)
-                    children.Add(child);
+                    yield return child;
             }
-
-            return children;
         }
 
         /// <summary>

+ 26 - 6
InABox.Core/DatabaseSchema/DatabaseSchema.cs

@@ -21,25 +21,45 @@ namespace InABox.Core
 
             public Action<object, object> Setter { get; set; }
 
+            public Func<object, object> Getter { get; set; }
+
             public SubObject(Type objectType, Type propertyType, string name)
             {
                 PropertyType = propertyType;
                 Name = name;
                 Setter = Expressions.Setter(objectType, name);
+                Getter = Expressions.Getter(objectType, name);
             }
         }
 
         private static Dictionary<Type, List<SubObject>> _subObjects { get; } = new Dictionary<Type, List<SubObject>>();
 
-        private static List<SubObject>? GetSubObjects(Type t)
+        private static List<SubObject>? GetSubObjectDefs(Type t)
         {
             CheckProperties(t);
             return _subObjects.GetValueOrDefault(t);
         }
 
+        public static IEnumerable<BaseObject> GetSubObjects(BaseObject obj)
+        {
+            var objs = GetSubObjectDefs(obj.GetType());
+            if(objs is null)
+            {
+                yield break;
+            }
+            foreach (var subObjectDef in objs)
+            {
+                var subObj = subObjectDef.Getter(obj);
+                if(subObj is BaseObject bObj)
+                {
+                    yield return bObj;
+                }
+            }
+        }
+
         public static void InitializeSubObjects(BaseObject obj)
         {
-            var objs = GetSubObjects(obj.GetType());
+            var objs = GetSubObjectDefs(obj.GetType());
             if(objs is null)
             {
                 return;
@@ -252,7 +272,7 @@ namespace InABox.Core
             {
                 var props = _properties.GetValueOrDefault(entityName);
                 var hasprops = props?.Any(x => x.Value is StandardProperty) == true;
-                if (type.IsSubclassOf(typeof(BaseObject)) && !hasprops)
+                if (!hasprops && type.IsSubclassOf(typeof(BaseObject)))
                     RegisterProperties(type);
             }
             catch (Exception e)
@@ -287,9 +307,9 @@ namespace InABox.Core
 
         public static void InitializeObject<TObject>(TObject entity) where TObject : BaseObject
         {
-            entity.UserProperties.Clear();
-            var props = Properties(entity.GetType()).Where(x => x is CustomProperty).ToArray();
-            foreach (var field in props) entity.UserProperties[field.Name] = DefaultValue(field.PropertyType);
+            entity.UserProperties.Load(Properties(entity.GetType())
+                .Where(x => x is CustomProperty)
+                .Select(x => new KeyValuePair<string, object?>(x.Name, x.PropertyType)));
         }
     }
 }

+ 6 - 0
InABox.Core/UserProperties.cs

@@ -131,6 +131,12 @@ namespace InABox.Core
             return Dictionary.Keys.ToArray();
         }
 
+        internal void Load(IEnumerable<KeyValuePair<string, object?>> pairs)
+        {
+            foreach (var pair in pairs)
+                Dictionary[pair.Key] = new UserProperty { Type = pair.Value != null ? pair.Value.GetType() : typeof(object), Value = pair.Value };
+        }
+
         internal void LoadFromDictionary(Dictionary<string, object?> defaultProperties)
         {
             foreach (var pair in defaultProperties)