public static void addJSCSRel(int jsObjID, object csObj, bool weakReference = false)
    {
        if (weakReference)
        {
            WeakReference wrObj = new WeakReference(csObj);
            var           Rel   = new JS_CS_Rel(jsObjID, wrObj);
            AddDictionary1(jsObjID, Rel);
            AddDictionary2(Rel);
        }
        else
        {
            JSCache.TypeInfo typeInfo = JSCache.GetTypeInfo(csObj.GetType());

            if (mDictionary1.ContainsKey(jsObjID))
            {
                if (typeInfo.IsValueType)
                {
                    mDictionary1.Remove(jsObjID);
                }
            }

            var Rel = new JS_CS_Rel(jsObjID, csObj);
            AddDictionary1(jsObjID, Rel);

            if (typeInfo.IsClass)
            {
                AddDictionary2(Rel);
            }
        }
    }
 private static void AddDictionary2(JS_CS_Rel Rel)
 {
     if (mDictionary2.ContainsKey(Rel.csObj))
     {
         mDictionary2[Rel.csObj] = Rel;
         Debug.LogError("mDictionary2 has same key to add:" + Rel.csObj + " - " + Rel.jsObjID);
     }
     else
     {
         mDictionary2.Add(Rel.csObj, Rel);
     }
 }
 private static void AddDictionary1(int jsObjID, JS_CS_Rel Rel)
 {
     if (mDictionary1.ContainsKey(jsObjID))
     {
         mDictionary1[jsObjID] = Rel;
         Debug.LogError("mDictionary1 has same key to add:" + jsObjID + " - " + Rel.csObj);
     }
     else
     {
         mDictionary1.Add(jsObjID, Rel);
     }
 }
示例#4
0
    public static void addJSCSRel(int jsObjID, object csObj, bool weakReference = false)
    {
        //if (csObj == null || csObj.Equals(null))

//         if (csObj != null && csObj is UnityEngine.Object)
//         {
//             if (csObj.Equals(null))
//             {
//                 Debug.LogError("JSMgr.addJSCSRel object == null, call stack:" + new System.Diagnostics.StackTrace().ToString());
//                 //throw new Exception();
//             }
//         }

        if (weakReference)
        {
            int           hash  = csObj.GetHashCode();
            WeakReference wrObj = new WeakReference(csObj);
            var           Rel   = new JS_CS_Rel(jsObjID, wrObj, hash);
            mDictionary1.Add(jsObjID, Rel);
            mDictionary2.Add(hash, Rel);
        }
        else
        {
            int hash = csObj.GetHashCode();
            JSCache.TypeInfo typeInfo = JSCache.GetTypeInfo(csObj.GetType());

            if (mDictionary1.ContainsKey(jsObjID))
            {
                if (typeInfo.IsValueType)
                {
                    mDictionary1.Remove(jsObjID);
                }
            }

#if UNITY_EDITOR
            if (mDictionary1.ContainsKey(jsObjID))
            {
                Debug.Log(">_<");
            }
#endif

            var Rel = new JS_CS_Rel(jsObjID, csObj, hash);
            mDictionary1.Add(jsObjID, Rel);

            if (typeInfo.IsClass)
            {
                mDictionary2.Add(hash, Rel);
            }
        }
    }
    public static void changeJSObj(int jsObjID, object csObjNew)
    {
        if (!csObjNew.GetType().IsValueType)
        {
            Debug.LogError("class can not call changeJSObj2");
            return;
        }
        JS_CS_Rel Rel;

        if (mDictionary1.TryGetValue(jsObjID, out Rel))
        {
            mDictionary1[jsObjID] = new JS_CS_Rel(jsObjID, csObjNew);
        }
    }
示例#6
0
    public static void ShutdownJSEngine()
    {
        shutDown = true;

        /*
         * 在 Shutdown 时,先主动删除 CSRepresentedObject
         * 现在已经没有必要再维护 id -> CSR.. 的关系了
         * 移除后,CSR.. 有可能还被其他地方引用,所以在这个函数中调用C# GC,也不一定会调用到 CSR.. 的析构
         * 后来在某个时刻析构被调用,在析构函数里有  removeJSCSRel ,那里会判断 round 是上一轮的所以忽略
         */
        List <int> keysToRemove  = new List <int>();
        List <int> hashsToRemove = new List <int>();

        foreach (var KV in mDictionary1)
        {
            JS_CS_Rel rel = KV.Value;
            if (rel.csObj is WeakReference)
            {
                if ((rel.csObj as WeakReference).Target is CSRepresentedObject)
                {
                    keysToRemove.Add(KV.Key);
                    hashsToRemove.Add(rel.hash);
                }
            }
        }
        foreach (var k in keysToRemove)
        {
            mDictionary1.Remove(k);
        }
        foreach (var h in hashsToRemove)
        {
            mDictionary2.Remove(h);
        }

        //
        // 并GC
        //
        System.GC.Collect();

        int Count = mDictionary1.Count;


        // There is a JS_GC called inside JSApi.ShutdownJSEngine
#if UNITY_EDITOR
        // DO NOT really cleanup everything, because we wanna start again
        JSApi.ShutdownJSEngine(0);
#else
        JSApi.ShutdownJSEngine(1);
#endif

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("After JSApi.ShutdownJSEngine: ");
        sb.Append("mDictionary1 count " + Count + " -> " + mDictionary1.Count + ", left elements(should only contain JSComponent):\n");

        /*
         * 到这里 mDictionary1 和 mDictionary2 应该只剩余 JSComponent 及其子类,原因是:
         * 除了 JSComponent 外,其他东西都应该在 JSApi.ShutdownJSEngine(0) 后被移除(他里面调用了 JS_GC)
         * 而 JSComponent 是没有垃圾回收回调的,他是在 OnDestroy 时从这2个字典里移除的
         * 这时候可能他的 OnDestroy 还没有执行,所以这2个字典里还会有他们
         */
        List <int> Keys = new List <int>(mDictionary1.Keys);
        foreach (var K in Keys)
        {
            if (!mDictionary1.ContainsKey(K))
            {
                continue;
            }

            JS_CS_Rel Rel = mDictionary1[K];
            sb.AppendLine(K.ToString() + " " + Rel.name);
        }
        Debug.Log(sb);

        allCallbackInfo.Clear();
        JSMgr.MoveJSCSRel2Old();
        mDictJSFun1.Clear();
        mDictJSFun2.Clear();
        evaluatedScript.Clear();
        CSRepresentedObject.s_objCount = 0;
        CSRepresentedObject.s_funCount = 0;
        jsEngineRound++;
    }
示例#7
0
    public static void ShutdownJSEngine()
    {
        shutDown = true;

        //
        // remove CSRepresentedObject first
        // no need to maintain id -> CSRepresentedObject now
        //
        // after remove, CSRepresentedObject may still be referenced, and ~CSRepresentedObject may not be called
        // some times later ~CSRepresentedObject is called -> removeJSCSRel -> round is ignored because it is last round
        //
        List <int> keysToRemove  = new List <int>();
        List <int> hashsToRemove = new List <int>();

        foreach (var KV in mDictionary1)
        {
            JS_CS_Rel rel = KV.Value;
            if (rel.csObj is WeakReference)
            {
                if ((rel.csObj as WeakReference).Target is CSRepresentedObject)
                {
                    keysToRemove.Add(KV.Key);
                    hashsToRemove.Add(rel.hash);
                }
            }
        }
        foreach (var k in keysToRemove)
        {
            mDictionary1.Remove(k);
        }
        foreach (var h in hashsToRemove)
        {
            mDictionary2.Remove(h);
        }

        System.GC.Collect();

        int Count = mDictionary1.Count;


        // There is a JS_GC called inside JSApi.ShutdownJSEngine
#if UNITY_EDITOR
        // DO NOT really cleanup everything, because we wanna start again
        JSApi.ShutdownJSEngine(0);
#else
        JSApi.ShutdownJSEngine(1);
#endif

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("After JSApi.ShutdownJSEngine: ");
        sb.Append("mDictionary1 count " + Count + " -> " + mDictionary1.Count + ", left elements(should only contain JSComponent):\n");
        //
        // here, mDictionary1 and mDictionary2 should only contain JSComponent and his subclasses, because:
        // everything should be removed after JSApi.ShutdownJSEngine(0) (it calls calls JS_GC)
        // JSComponent is nomally be removed during OnDestroy, but his OnDestroy may not be called yet here
        //
        List <int> Keys = new List <int>(mDictionary1.Keys);
        foreach (var K in Keys)
        {
            if (!mDictionary1.ContainsKey(K))
            {
                continue;
            }

            JS_CS_Rel Rel = mDictionary1[K];
            sb.AppendLine(K.ToString() + " " + Rel.name);
        }
        Debug.Log(sb);

        allCallbackInfo.Clear();
        JSMgr.MoveJSCSRel2Old();
        mDictJSFun1.Clear();
        mDictJSFun2.Clear();
        evaluatedScript.Clear();
        CSRepresentedObject.s_objCount = 0;
        CSRepresentedObject.s_funCount = 0;
        jsEngineRound++;
    }