Example #1
0
        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();
        }
Example #2
0
        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();
        }