diff --git a/source/funkin/util/StructureUtil.hx b/source/funkin/util/StructureUtil.hx index 351d0e0a8..f94de4652 100644 --- a/source/funkin/util/StructureUtil.hx +++ b/source/funkin/util/StructureUtil.hx @@ -1,5 +1,6 @@ package funkin.util; +import funkin.util.tools.MapTools; import haxe.DynamicAccess; /** @@ -26,6 +27,57 @@ class StructureUtil return result; } + public static function toMap(a:Dynamic):haxe.ds.Map + { + var result:haxe.ds.Map = []; + + for (field in Reflect.fields(a)) + { + result.set(field, Reflect.field(a, field)); + } + + return result; + } + + public static function isMap(a:Dynamic):Bool + { + return Std.isOfType(a, haxe.Constraints.IMap); + } + + public static function isObject(a:Dynamic):Bool + { + switch (Type.typeof(a)) + { + case TObject: + return true; + default: + return false; + } + } + + public static function isPrimitive(a:Dynamic):Bool + { + switch (Type.typeof(a)) + { + case TInt | TFloat | TBool: + return true; + case TClass(c): + return false; + case TEnum(e): + return false; + case TObject: + return false; + case TFunction: + return false; + case TNull: + return true; + case TUnknown: + return false; + default: + return false; + } + } + /** * Merge two structures, with the second overwriting the first. * Performs a DEEP clone, where child structures are also merged recursively. @@ -37,6 +89,18 @@ class StructureUtil { if (a == null) return b; if (b == null) return null; + if (isPrimitive(a) && isPrimitive(b)) return b; + if (isMap(b)) + { + if (isMap(a)) + { + return MapTools.merge(a, b); + } + else + { + return StructureUtil.toMap(a).merge(b); + } + } if (!Reflect.isObject(a) || !Reflect.isObject(b)) return b; var result:DynamicAccess = Reflect.copy(a);