internal static ScriptType GetDictionaryItemType(Box box, ScriptType type) { if (type == ScriptType.Null) { return(box.DefaultType); } // BoxID = 1 is Key // BoxID = 2 is Value return(box.DefaultType != null ? new ScriptType(type.GetGenericArguments()[box.ID == 1 ? 0 : 1]) : type); }
private static void GetEntries(MemberInfoPath.Entry member, Stack <MemberInfoPath.Entry> membersPath, List <TypeEntry> result, List <object> values, Stack <object> refStack, ScriptType memberType, object memberValue) { membersPath.Push(member); var path = new MemberInfoPath(membersPath); var beforeCount = result.Count; // Check if record object sub members (skip Flax objects) // It's used for ref types but not null types and with checking cyclic references if ((memberType.IsClass || memberType.IsArray || typeof(IList).IsAssignableFrom(memberType.Type) || typeof(IDictionary).IsAssignableFrom(memberType.Type)) && memberValue != null && !refStack.Contains(memberValue)) { if (memberType.IsArray && !typeof(FlaxEngine.Object).IsAssignableFrom(memberType.GetElementType())) { // Array var array = (Array)memberValue; var elementType = new ScriptType(memberType.GetElementType()); var length = array.Length; refStack.Push(memberValue); for (int i = 0; i < length; i++) { var value = array.GetValue(i); GetEntries(new MemberInfoPath.Entry(member.Member, i), membersPath, result, values, refStack, elementType, value); } refStack.Pop(); } else if (typeof(IList).IsAssignableFrom(memberType.Type) && !typeof(FlaxEngine.Object).IsAssignableFrom(memberType.GetElementType())) { // List var list = (IList)memberValue; var genericArguments = memberType.GetGenericArguments(); var elementType = new ScriptType(genericArguments[0]); var count = list.Count; refStack.Push(memberValue); for (int i = 0; i < count; i++) { var value = list[i]; GetEntries(new MemberInfoPath.Entry(member.Member, i), membersPath, result, values, refStack, elementType, value); } refStack.Pop(); } else if (typeof(IDictionary).IsAssignableFrom(memberType.Type)) { // Dictionary var dictionary = (IDictionary)memberValue; var genericArguments = memberType.GetGenericArguments(); var valueType = new ScriptType(genericArguments[1]); foreach (var key in dictionary.Keys) { var value = dictionary[key]; GetEntries(new MemberInfoPath.Entry(member.Member, key), membersPath, result, values, refStack, valueType, value); } } else if (memberType.IsClass && !new ScriptType(typeof(FlaxEngine.Object)).IsAssignableFrom(memberType)) { // Object refStack.Push(memberValue); GetEntries(memberValue, membersPath, memberType, result, values, refStack); refStack.Pop(); } } var afterCount = result.Count; result.Add(new TypeEntry(path, afterCount - beforeCount)); var memberValueType = TypeUtils.GetObjectType(memberValue); if (memberValue != null && memberValueType.IsStructure) { var json = JsonSerializer.Serialize(memberValue); var clone = JsonSerializer.Deserialize(json, memberValueType.Type); values.Add(clone); } else { values.Add(memberValue); } membersPath.Pop(); }