public static void WriteAll(this JsonHelperWriter json, JSONRule rule, object obj, MemberInfo[] infos)
 {
     for (int i = 0; i < infos.Length; i++)
     {
         rule.Serialize(json, obj, infos[i]);
     }
 }
    public static JSONRule GetJSONRule(this Type type_)
    {
        Type     type = type_;
        JSONRule config;

        if (Rules.TryGetValue(type_, out config))
        {
            return(config);
        }

        while (type != null)
        {
            for (int i = 0; i < _RuleTypes.Length; i++)
            {
                Type t  = _RuleTypes[i];
                Type bi = t;
                while ((bi = bi.BaseType) != null)
                {
                    if (!bi.IsGenericType || bi.GetGenericTypeDefinition() != typeof(JSONRule <>))
                    {
                        continue;
                    }
                    if (type == bi.GetGenericArguments()[0])
                    {
                        return(Rules[type_] = ((JSONRule)t.GetConstructor(Type.EmptyTypes).Invoke(a_object_0)).Fill(type_));
                    }
                }
            }
            type = type.BaseType;
        }

        if (type_.IsValueType)
        {
            return(Rules[type_] = new JSONValueTypeRule().Fill(type_));
        }

        return(Rules[type_] = new JSONRule().Fill(type_));
    }
    public static void Write(this JsonHelperWriter json, object obj)
    {
        if (obj == null)
        {
            json.WriteNull();
            return;
        }
        if (obj is JToken)
        {
            json.WriteRawValue(obj.ToString());
            return;
        }

        Type type = obj.GetType();

        if (obj is Enum || obj is string || obj is byte[] || type.IsPrimitive)
        {
            json.WriteValue(obj);
            return;
        }

        if (obj is Type)
        {
            json.WriteMetaType((Type)obj);
            return;
        }

        if (json.TryWriteMetaReference(obj, true))
        {
            return;
        }

        json.Push(obj);

        JSONRule rule = type.GetJSONRule();

        if (rule.GetType() == t_JSONRule)
        {
            if (obj is IList)
            {
                IList list = (IList)obj;
                json.WriteStartArray();
                if (type.IsArray)
                {
                    json.WriteMetaArrayData(META.ARRAYTYPE_ARRAY, list.Count);
                }
                else
                {
                    json.WriteMetaArrayData(META.ARRAYTYPE_LIST);
                }

                foreach (object o in list)
                {
                    json.Write(o);
                }
                json.WriteEndArray();
                json.Pop();
                return;
            }

            if (obj is IDictionary)
            {
                IDictionary dict = (IDictionary)obj;
                json.WriteStartArray();
                json.WriteMetaArrayData(META.ARRAYTYPE_MAP);
                foreach (DictionaryEntry e in dict)
                {
                    json.Write(e);
                }
                json.WriteEndArray();
                json.Pop();
                return;
            }
        }

        UnityEngine.Object so = (UnityEngine.Object)(
            ((object)(obj as GameObject)) ??
            ((object)(obj as ScriptableObject)) ??
            ((object)(obj as Component))
            );
        string name = so?.name;

        if (json.RootWritten && (json.DumpRelatively || SharedDir != null) && !string.IsNullOrEmpty(name) && !(obj is Transform))
        {
            if (SharedDir == null && json.DumpRelatively)
            {
                Directory.CreateDirectory(json.RelativeDir);
                string dumppath = Path.Combine(json.RelativeDir, name + ".json");
                if (!File.Exists(dumppath))
                {
                    using (JsonHelperWriter ext = OpenWriteJSON(dumppath)) {
                        ext.AddPath(json);
                        ext.RelativeDir = Path.Combine(json.RelativeDir, name);
                        ext.Write(obj);
                    }
                }
                json.WriteMetaExternal(name, META.EXTERNAL_IN_RELATIVE);
            }
            else if (SharedDir != null)
            {
                string path;
                if (_DumpObjPathMap.TryGetValue(so, out path))
                {
                    json.WriteMetaExternal(path, META.EXTERNAL_IN_SHARED);
                    json.Pop();
                    return;
                }
                path = type.Name + "s/" + name;

                int id;
                if (!_DumpNameIdMap.TryGetValue(path, out id))
                {
                    id = -1;
                }
                _DumpNameIdMap[name] = ++id;

                if (id != 0)
                {
                    path += "." + id;
                }
                _DumpObjPathMap[so] = path;

                string dumppath = Path.Combine(SharedDir, path.Replace('/', Path.DirectorySeparatorChar) + ".json");
                Directory.GetParent(dumppath).Create();
                if (!File.Exists(dumppath))
                {
                    using (JsonHelperWriter ext = OpenWriteJSON(dumppath)) {
                        ext.AddPath(json);
                        ext.Write(obj);
                    }
                }
                json.WriteMetaExternal(path, META.EXTERNAL_IN_SHARED);
            }
            json.Pop();
            return;
        }

        json.RootWritten = true;
        json.WriteStartObject();
        rule.WriteMetaHeader(json, obj);
        _OnBeforeSerialize(obj);
        rule.Serialize(json, obj);
        json.WriteEndObject();
        json.Pop();
    }
 public static void Write(this JsonHelperWriter json, JSONRule rule, object obj, MemberInfo info)
 {
     rule.Serialize(json, obj, info);
 }