コード例 #1
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            if (DuktapeDLL.duk_is_object(ctx, idx) ||/* && check if js delegate type (hidden property) */
                DuktapeDLL.duk_is_function(ctx, idx))
            {
                DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE_WEAK);
                var refid = DuktapeDLL.duk_get_int(ctx, -1);
                DuktapeDLL.duk_pop(ctx);

                var             cache = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetTypedWeakObject(refid, out fn) && fn != null)
                {
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                var heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx));
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                refid = cache.AddWeakObject(fn);
                DuktapeDLL.duk_unity_set_prop_i(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE_WEAK, refid);
                cache.AddJSValue(o, heapptr);
                return(true);
            }
            o = null;
            return(false);
        }
コード例 #2
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            if (DuktapeDLL.duk_is_object(ctx, idx) ||/* && check if js delegate type (hidden property) */
                DuktapeDLL.duk_is_function(ctx, idx))
            {
                var             heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                var             cache   = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetDelegate(heapptr, out fn))
                {
                    // Debug.LogWarningFormat("cache hit {0}", heapptr);
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx));
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                // Debug.LogWarningFormat("cache create : {0}", heapptr);
                cache.AddDelegate(heapptr, fn);
                return(true);
            }
            o = null;
            return(false);
        }
コード例 #3
0
 public static bool duk_get_type(IntPtr ctx, int idx, out Type o)
 {
     if (DuktapeDLL.duk_is_string(ctx, idx))
     {
         var name = DuktapeDLL.duk_get_string(ctx, idx);
         o = DuktapeAux.GetType(name);
         return(o != null);
     }
     else
     {
         //TODO: 增加一个隐藏属性记录jsobject对应类型 (constructor, object)
         if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_EXPORTED_REFID))
         {
             var vm    = DuktapeVM.GetVM(ctx);
             var refid = DuktapeDLL.duk_get_uint(ctx, -1);
             DuktapeDLL.duk_pop(ctx);
             o = vm.GetExportedType(refid);
             // Debug.Log($"get type from exported registry {o}:{refid}");
             return(o != null);
         }
         else if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
         {
             var cache = DuktapeVM.GetObjectCache(ctx);
             var refid = DuktapeDLL.duk_get_int(ctx, -1);
             DuktapeDLL.duk_pop(ctx);
             cache.TryGetTypedObject(refid, out o);
             // Debug.Log($"get type from objectcache registry {o}:{refid}");
             return(o != null);
         }
     }
     o = null;
     return(false);
 }
コード例 #4
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            //TODO: 20200320 !!! 如果 o 不是 jsobject, 且是 Delegate 但不是 DuktapeDelegate, 则 ... 处理

            if (DuktapeDLL.duk_is_object(ctx, idx) || DuktapeDLL.duk_is_function(ctx, idx))
            {
                var             heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                var             cache   = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetDelegate(heapptr, out fn))
                {
                    // Debug.LogWarningFormat("cache hit {0}", heapptr);
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx), heapptr);
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                // Debug.LogWarningFormat("cache create : {0}", heapptr);
                cache.AddDelegate(heapptr, fn);
                return(true);
            }
            // else if (DuktapeDLL.duk_is_object(ctx, idx))
            // {
            //     return duk_get_classvalue<T>(ctx, idx, out o);
            // }
            o = null;
            return(false);
        }
コード例 #5
0
 public static bool duk_get_type(IntPtr ctx, int idx, out Type o)
 {
     if (DuktapeDLL.duk_is_string(ctx, idx))
     {
         var name = DuktapeDLL.duk_get_string(ctx, idx);
         o = DuktapeAux.GetType(name);
         return(o != null);
     }
     else
     {
         uint refid_t;
         //TODO: 增加一个隐藏属性记录jsobject对应类型 (constructor, object)
         if (DuktapeDLL.duk_unity_get_type_refid(ctx, idx, out refid_t))
         {
             var vm = DuktapeVM.GetVM(ctx);
             o = vm.GetExportedType(refid_t);
             // Debug.Log($"get type from exported registry {o}:{refid}");
             return(o != null);
         }
         else
         {
             int refid;
             if (DuktapeDLL.duk_unity_get_refid(ctx, idx, out refid))
             {
                 var cache = DuktapeVM.GetObjectCache(ctx);
                 cache.TryGetTypedObject(refid, out o);
                 // Debug.Log($"get type from objectcache registry {o}:{refid}");
                 return(o != null);
             }
         }
     }
     o = null;
     return(false);
 }
コード例 #6
0
        // private static void duk_unity_unref_delegate(IntPtr ctx, uint refid, object target)
        // {
        //     var cache = DuktapeVM.GetObjectCache(ctx);
        //     cache.RemoveJSValue(target);
        // }

        private static void duk_unity_unref(IntPtr ctx, uint refid, object target)
        {
            var cache = DuktapeVM.GetObjectCache(ctx);
            var t     = cache.RemoveDelegate((IntPtr)target);

            // Debug.LogErrorFormat("release delegate ptr {0} {1}", target, t);
            DuktapeDLL.duk_unity_unref(ctx, refid);
        }
コード例 #7
0
        private static void duk_unity_unref(IntPtr ctx, uint refid, object target)
        {
            var cache = DuktapeVM.GetObjectCache(ctx);

            // cache.RemoveJSValue(target);
            cache.RemoveDelegate((IntPtr)target);
            DuktapeDLL.duk_unity_unref(ctx, refid);
        }
コード例 #8
0
        public static bool duk_rebind_native(IntPtr ctx, int idx, object o)
        {
            int id;

            if (DuktapeDLL.duk_unity_get_refid(ctx, idx, out id))
            {
                return(DuktapeVM.GetObjectCache(ctx).ReplaceObject(id, o));
            }
            return(false);
        }
コード例 #9
0
 protected static int object_dtor(IntPtr ctx)
 {
     if (DuktapeDLL.duk_get_prop_string(ctx, 0, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeVM.GetObjectCache(ctx)?.RemoveObject(id);
     }
     DuktapeDLL.duk_pop(ctx); // pop native
     return(0);
 }
コード例 #10
0
        protected static int object_dtor(IntPtr ctx)
        {
            int id;

            if (DuktapeDLL.duk_unity_get_refid(ctx, 0, out id))
            {
                // Debug.LogErrorFormat("remove refid {0}", id);
                DuktapeVM.GetObjectCache(ctx)?.RemoveObject(id);
            }
            return(0);
        }
コード例 #11
0
        public static bool duk_get_cached_object(IntPtr ctx, int idx, out object o)
        {
            int id;

            if (DuktapeDLL.duk_unity_get_refid(ctx, idx, out id))
            {
                return(DuktapeVM.GetObjectCache(ctx).TryGetObject(id, out o));
            }
            //TODO: if o is Delegate, try get from delegate cache list
            o = null;
            return(false);
        }
コード例 #12
0
        // push 一个对象实例 (调用者需要自行负责提前null检查)
        private static void duk_push_object(IntPtr ctx, object o)
        {
            var    cache = DuktapeVM.GetObjectCache(ctx);
            IntPtr heapptr;

            if (cache.TryGetJSValue(o, out heapptr))
            {
                DuktapeDLL.duk_push_heapptr(ctx, heapptr);
                return;
            }
            DuktapeDLL.duk_push_object(ctx);
            duk_bind_native(ctx, -1, o);
        }
コード例 #13
0
        public static bool duk_rebind_native(IntPtr ctx, int idx, object o)
        {
            if (DuktapeDLL.duk_is_null_or_undefined(ctx, idx)) // or check for object?
            {
                return(true);
            }
            int id;

            if (DuktapeDLL.duk_unity_get_refid(ctx, idx, out id))
            {
                return(DuktapeVM.GetObjectCache(ctx).ReplaceObject(id, o));
            }
            return(false);
        }
コード例 #14
0
        // push 一个对象实例 (调用者需要自行负责提前null检查)
        private static void duk_push_object(IntPtr ctx, object o)
        {
            var    cache = DuktapeVM.GetObjectCache(ctx);
            IntPtr heapptr;

            if (cache.TryGetJSValue(o, out heapptr))
            {
                // Debug.LogWarningFormat("cache hit push {0}", heapptr);
                DuktapeDLL.duk_push_heapptr(ctx, heapptr);
                return;
            }
            DuktapeDLL.duk_push_object(ctx);
            duk_bind_native(ctx, -1, o);
        }
コード例 #15
0
 public static bool duk_get_cached_object(IntPtr ctx, int idx, out object o)
 {
     if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeDLL.duk_pop(ctx);
         return(DuktapeVM.GetObjectCache(ctx).TryGetObject(id, out o));
     }
     else
     {
         DuktapeDLL.duk_pop(ctx);
     }
     o = null;
     return(false);
 }
コード例 #16
0
 public static bool duk_rebind_native(IntPtr ctx, int idx, object o)
 {
     if (DuktapeDLL.duk_is_null_or_undefined(ctx, idx)) // or check for object?
     {
         return(true);
     }
     if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeDLL.duk_pop(ctx); // pop OBJ_PROP_NATIVE
         return(DuktapeVM.GetObjectCache(ctx).ReplaceObject(id, o));
     }
     else
     {
         DuktapeDLL.duk_pop(ctx);
     }
     return(false);
 }
コード例 #17
0
        public static void duk_bind_native(IntPtr ctx, int idx, object o)
        {
            var cache = DuktapeVM.GetObjectCache(ctx);
            var id    = cache.AddObject(o);

            DuktapeDLL.duk_unity_set_refid(ctx, idx, id);
            if (DuktapeVM.GetVM(ctx).PushChainedPrototypeOf(ctx, o.GetType()))
            {
                DuktapeDLL.duk_set_prototype(ctx, -2);
            }
            else
            {
                Debug.LogWarning($"no prototype found for {o.GetType()}");
            }
            if (!o.GetType().IsValueType)
            {
                var heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                cache.AddJSValue(o, heapptr);
            }
        }
コード例 #18
0
 private static void duk_unity_unref(IntPtr ctx, uint refid, object target)
 {
     DuktapeVM.GetObjectCache(ctx).RemoveJSValue(target);
     DuktapeDLL.duk_unity_unref(ctx, refid);
 }
コード例 #19
0
        protected static bool duk_match_type(IntPtr ctx, int idx, Type type)
        {
            if (type == null)
            {
                return(true);
            }
            if (type == typeof(object))
            {
                return(true);
            }
            if (type == typeof(Type))
            {
                Type otype;
                return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type
                // return otype == type;
            }
            var jstype = DuktapeDLL.duk_get_type(ctx, idx);

            switch (jstype)
            {
            // case duk_type_t.DUK_TYPE_NONE:
            case duk_type_t.DUK_TYPE_OBJECT:     // objects, arrays, functions, threads
                if (DuktapeDLL.duk_is_array(ctx, idx))
                {
                    if (!type.IsArray && !_assignableFromArray.Contains(type))
                    {
                        return(false);
                    }
                }
                else if (DuktapeDLL.duk_is_function(ctx, idx))
                {
                    //TODO: 完善处理 delegate
                    return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate));
                }
                else if (DuktapeDLL.duk_is_thread(ctx, idx))
                {
                    return(false);
                }

                int refid;
                if (duk_get_native_refid(ctx, idx, out refid))
                {
                    var cache = DuktapeVM.GetObjectCache(ctx);
                    return(cache.MatchObjectType(refid, type));
                }

                int typeid;
                if (DuktapeDLL.duk_unity_get_type_refid(ctx, idx, out typeid))
                {
                    var vm    = DuktapeVM.GetVM(ctx);
                    var eType = vm.GetExportedType(typeid);
                    if (eType != null)
                    {
                        // Debug.LogFormat("match type? {0} {1} {2}", eType, type, typeid);
                        return(eType == type);
                    }
                    // Debug.LogFormat("match type {0} with typeid {1}", type, typeid);
                }
                return(type.IsSubclassOf(typeof(DuktapeValue)));

            case duk_type_t.DUK_TYPE_NUMBER:
                return(type.IsPrimitive || type.IsEnum);

            case duk_type_t.DUK_TYPE_STRING:
                return(type == typeof(string));

            case duk_type_t.DUK_TYPE_UNDEFINED:
            case duk_type_t.DUK_TYPE_NULL:
                return(!type.IsValueType && !type.IsPrimitive);

            case duk_type_t.DUK_TYPE_BOOLEAN:
                return(type == typeof(bool));

            case duk_type_t.DUK_TYPE_BUFFER:
                return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */);

            case duk_type_t.DUK_TYPE_POINTER:
            // return type == typeof(DuktapePointer);
            case duk_type_t.DUK_TYPE_LIGHTFUNC:
            default:
                return(false);
            }
        }
コード例 #20
0
        protected static bool duk_match_type(IntPtr ctx, int idx, Type type)
        {
            if (type == null)
            {
                return(true);
            }
            if (type == typeof(object))
            {
                return(true);
            }
            if (type == typeof(Type))
            {
                Type otype;
                return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type
                // return otype == type;
            }
            var jstype = DuktapeDLL.duk_get_type(ctx, idx);

            switch (jstype)
            {
            // case duk_type_t.DUK_TYPE_NONE:
            case duk_type_t.DUK_TYPE_OBJECT:     // objects, arrays, functions, threads
                if (DuktapeDLL.duk_is_array(ctx, idx))
                {
                    if (!type.IsArray && !_assignableFromArray.Contains(type))
                    {
                        return(false);
                    }
                }
                else if (DuktapeDLL.duk_is_function(ctx, idx))
                {
                    //TODO: 完善处理 delegate
                    return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate));
                }
                else if (DuktapeDLL.duk_is_thread(ctx, idx))
                {
                    return(false);
                }
                int refid;
                //TODO: 根据记录在jsobject 上的 分类标记 做进一步分支 (类型, 实例, 或特定优化类型)
                if (duk_get_native_refid(ctx, idx, out refid))
                {
                    var cache = DuktapeVM.GetObjectCache(ctx);
                    return(cache.MatchObjectType(refid, type));
                }
                return(true);

            case duk_type_t.DUK_TYPE_NUMBER:
                return(type.IsPrimitive || type.IsEnum);

            case duk_type_t.DUK_TYPE_STRING:
                return(type == typeof(string));

            case duk_type_t.DUK_TYPE_UNDEFINED:
            case duk_type_t.DUK_TYPE_NULL:
                return(!type.IsValueType && !type.IsPrimitive);

            case duk_type_t.DUK_TYPE_BOOLEAN:
                return(type == typeof(bool));

            case duk_type_t.DUK_TYPE_BUFFER:
                return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */);

            case duk_type_t.DUK_TYPE_POINTER:
            // return type == typeof(DuktapePointer);
            case duk_type_t.DUK_TYPE_LIGHTFUNC:
            default:
                return(false);
            }
        }