Ejemplo n.º 1
0
        public static bool js_get_delegate(JSContext ctx, JSValue val, Type delegateType, out Delegate o)
        {
            //TODO: 20200320 !!! 如果 o 不是 jsobject, 且是 Delegate 但不是 ScriptDelegate, 则 ... 处理
            if (val.IsNullish())
            {
                o = null;
                return(true);
            }

            if (JSApi.JS_IsObject(val) || JSApi.JS_IsFunction(ctx, val) == 1)
            {
                ScriptDelegate fn;
                var            cache = ScriptEngine.GetObjectCache(ctx);

                if (cache.TryGetDelegate(val, out fn))
                {
                    // Debug.LogWarningFormat("cache hit {0}", heapptr);
                    o = fn.Match(delegateType);
                    if (o == null)
                    {
                        var types = ScriptEngine.GetTypeDB(ctx);
                        var func  = types.GetDelegateFunc(delegateType);
                        o = Delegate.CreateDelegate(delegateType, fn, func, false);
                        if (o != null)
                        {
                            fn.Add(o);
                        }
                    }
                    return(o != null);
                }
                else
                {
                    // 默认赋值操作
                    var types = ScriptEngine.GetTypeDB(ctx);
                    var func  = types.GetDelegateFunc(delegateType);

                    if (func == null)
                    {
                        o = null;
                        return(false);
                    }

                    fn = new ScriptDelegate(ScriptEngine.GetContext(ctx), val);
                    o  = Delegate.CreateDelegate(delegateType, fn, func, false);
                    if (o != null)
                    {
                        fn.Add(o);
                    }

                    // ScriptDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                    // 会出现的问题是, 如果 c# 没有对 ScriptDelegate 的强引用, 那么反复 get_delegate 会重复创建 ScriptDelegate
                    // Debug.LogWarningFormat("cache create : {0}", heapptr);
                    cache.AddDelegate(val, fn);
                    return(o != null);
                }
            }
            // else if (DuktapeDLL.duk_is_object(ctx, idx))
            // {
            //     return js_get_classvalue<T>(ctx, idx, out o);
            // }
            o = null;
            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 从 JSValue 反推 Delegate, JSValue 可能是一个 js function, cs delegate (js object) <br/>
        /// 注意: 会自动创建 ScriptDelegate 映射
        /// </summary>
        public static bool js_get_delegate(JSContext ctx, JSValue val, Type delegateType, out Delegate o)
        {
            if (val.IsNullish())
            {
                o = null;
                return(true);
            }

            // 检查 val 是否是一个委托对象 wrapped object
            if (JSApi.JS_IsObject(val))
            {
                if (js_get_classvalue <Delegate>(ctx, val, out o))
                {
                    return(o == null || o.GetType() == delegateType);
                }
                if (JSApi.JS_IsFunction(ctx, val) == 1)
                {
                    ScriptDelegate fn;
                    var            cache = ScriptEngine.GetObjectCache(ctx);

                    if (cache.TryGetDelegate(val, out fn))
                    {
                        // 已经存在映射关系, 找出符合预期类型的委托
                        o = fn.Match(delegateType);
                        if (o == null)
                        {
                            // 存在 JSValue => Delegate 的多重映射
                            var types = ScriptEngine.GetTypeDB(ctx);
                            var func  = types.GetDelegateFunc(delegateType);
                            o = Delegate.CreateDelegate(delegateType, fn, func, false);
                            if (o != null)
                            {
                                fn.Add(o);
                            }
                        }
                        return(o != null);
                    }
                    else
                    {
                        // 建立新的映射关系
                        var context = ScriptEngine.GetContext(ctx);
                        var types   = context.GetTypeDB();
                        var func    = types.GetDelegateFunc(delegateType);

                        if (func == null)
                        {
                            o = null;
                            return(false);
                        }

                        fn = new ScriptDelegate(context, val);
                        o  = Delegate.CreateDelegate(delegateType, fn, func, false);
                        if (o != null)
                        {
                            fn.Add(o);
                        }

                        return(o != null);
                    }
                }
            }

            o = null;
            return(false);
        }