예제 #1
0
 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);
 }
예제 #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();
        }