private static void GetEntries(MemberInfoPath.Entry member, Stack <MemberInfoPath.Entry> membersPath, Type type, List <TypeEntry> result, List <object> values, Stack <object> refStack, Type 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 bu not null types and with checking cyclic references if ((memberType.IsClass || memberType.IsArray || typeof(IList).IsAssignableFrom(memberType)) && memberValue != null && !refStack.Contains(memberValue)) { if (memberType.IsArray && !typeof(FlaxEngine.Object).IsAssignableFrom(memberType.GetElementType())) { var array = (Array)memberValue; var elementType = memberType.GetElementType(); var length = array.Length; refStack.Push(memberValue); for (int i = 0; i < length; i++) { var elementValue = array.GetValue(i); GetEntries(new MemberInfoPath.Entry(member.Member, i), membersPath, type, result, values, refStack, elementType, elementValue); } refStack.Pop(); } else if (typeof(IList).IsAssignableFrom(memberType) && !typeof(FlaxEngine.Object).IsAssignableFrom(memberType.GetElementType())) { var list = (IList)memberValue; var elementType = memberType.GetGenericArguments()[0]; var count = list.Count; refStack.Push(memberValue); for (int i = 0; i < count; i++) { var elementValue = list[i]; GetEntries(new MemberInfoPath.Entry(member.Member, i), membersPath, type, result, values, refStack, elementType, elementValue); } refStack.Pop(); } else if (memberType.IsClass && !typeof(FlaxEngine.Object).IsAssignableFrom(memberType)) { refStack.Push(memberValue); GetEntries(memberValue, membersPath, memberType, result, values, refStack); refStack.Pop(); } } var afterCount = result.Count; result.Add(new TypeEntry(path, afterCount - beforeCount)); values.Add(memberValue); membersPath.Pop(); }
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(); }