Beispiel #1
0
        public void Destroy()
        {
            try
            {
                _instance = null;
                if (_ctx != null)
                {
                    var ctx = _ctx.rawValue;
                    _ctx.Destroy();
                    _ctx            = null;
                    _lastContextPtr = IntPtr.Zero;
                    _lastContext    = null;
                    _contexts.Clear();
                    _objectCache.Clear();
                    DuktapeDLL.duk_unity_destroy_heap(ctx);
                    // Debug.LogWarning("duk_destroy_heap");
                }

                if (_updateTimer != 0)
                {
                    DuktapeRunner.Clear(_updateTimer);
                    _updateTimer = 0;
                }
            }
            finally
            {
                if (_memAllocPool != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(_memAllocPool);
                    _memAllocPool = IntPtr.Zero;
                }
            }
        }
Beispiel #2
0
        public static void addContext(DuktapeContext context)
        {
            var ctx = context.rawValue;

            _contexts[ctx]  = context;
            _lastContext    = context;
            _lastContextPtr = ctx;
        }
Beispiel #3
0
        public static void addContext(DuktapeContext context)
        {
            var ctx = context.rawValue;

            if (ctx != IntPtr.Zero)
            {
                _contexts[ctx]  = context;
                _lastContext    = context;
                _lastContextPtr = ctx;
            }
        }
Beispiel #4
0
        public DuktapeVM(IO.ByteBufferAllocator allocator = null)
        {
            _instance            = this;
            _byteBufferAllocator = allocator;

            var ctx = DuktapeDLL.duk_create_heap_default();

            _ctx = new DuktapeContext(this, ctx);
            DuktapeAux.duk_open(ctx);
            DuktapeVM.duk_open_module(ctx);
            DuktapeDLL.duk_unity_open(ctx);
        }
Beispiel #5
0
        // poolSize: 预分配内存
        public DuktapeVM(IO.ByteBufferAllocator allocator = null, int poolSize = 0)
        {
            _instance            = this;
            _byteBufferAllocator = allocator;
            _memAllocPoolSize    = poolSize >= 0 ? (uint)poolSize : 0;
            _memAllocPool        = _memAllocPoolSize != 0 ? Marshal.AllocHGlobal(poolSize) : IntPtr.Zero;
            var ctx = DuktapeDLL.duk_unity_create_heap(_memAllocPool, _memAllocPoolSize);

            _ctx = new DuktapeContext(this, ctx);
            DuktapeDLL.duk_unity_open(ctx);
            DuktapeAux.duk_open(ctx);
            DuktapeVM.duk_open_module(ctx);
        }
Beispiel #6
0
        public static void removeContext(DuktapeContext context)
        {
            var ctx = context.rawValue;

            if (ctx != IntPtr.Zero)
            {
                _contexts.Remove(ctx);
                if (_lastContext == context)
                {
                    _lastContext    = null;
                    _lastContextPtr = IntPtr.Zero;
                }
            }
        }
Beispiel #7
0
        private static DuktapeContext TryGetContext(IntPtr ctx)
        {
            DuktapeContext context;

            if (_contexts.TryGetValue(ctx, out context))
            {
                _lastContext    = context;
                _lastContextPtr = ctx;
                return(context);
            }
            // fixme 如果是 thread 则获取对应 main context
            // DuktapeDLL.duk_push_current_thread(ctx);
            // var parent = DuktapeDLL.duk_get_parent_context(ctx, -1);
            // DuktapeDLL.duk_pop(ctx);
            // return parent != ctx ? TryGetContext(parent) : null;
            return(null);
        }
Beispiel #8
0
        public DuktapeThread(DuktapeFunction fn)
        {
            var ctx = fn.ctx;
            var vm  = DuktapeVM.GetContext(ctx).vm;
            var idx = DuktapeDLL.duk_push_thread(ctx);

            DuktapeDLL.duk_dup(ctx, -1);
            var ptr = DuktapeDLL.duk_get_heapptr(ctx, -1);

            _thread        = new DuktapeValue(ctx, DuktapeDLL.duk_unity_ref(ctx), ptr);
            _threadContext = new DuktapeContext(vm, DuktapeDLL.duk_get_context(ctx, idx));
            if (fn.Push(_threadContext.rawValue))
            {
            }

            DuktapeDLL.duk_pop(ctx);
        }
Beispiel #9
0
        public static DuktapeContext GetContext(IntPtr ctx)
        {
            if (_lastContextPtr == ctx)
            {
                return(_lastContext);
            }
            DuktapeContext context;

            if (_contexts.TryGetValue(ctx, out context))
            {
                _lastContext    = context;
                _lastContextPtr = ctx;
                return(context);
            }
            // fixme 如果是 thread 则获取对应 main context
            return(null);
        }
Beispiel #10
0
        public void Destroy()
        {
            _instance = null;
            if (_ctx != null)
            {
                var ctx = _ctx.rawValue;
                _ctx.onDestroy();
                _ctx            = null;
                _lastContextPtr = IntPtr.Zero;
                _lastContext    = null;
                _contexts.Clear();
                _objectCache.Clear();
                DuktapeDLL.duk_destroy_heap_default(ctx);
                // Debug.LogWarning("duk_destroy_heap");
            }

            if (_updateTimer != 0)
            {
                DuktapeRunner.Clear(_updateTimer);
                _updateTimer = 0;
            }
        }
Beispiel #11
0
        private static IEnumerator DuktapeCoroutineRun(DuktapeObject val)
        {
            // scratch code

            val.PushProperty(val.ctx, "thread");
            var thread = DuktapeDLL.duk_get_context(val.ctx, -1);

            DuktapeDLL.duk_pop(val.ctx);
            if (thread == IntPtr.Zero || thread == val.ctx)
            {
                Debug.LogError("invalid thread ptr");
                yield break;
            }
            var  context = new DuktapeContext(val.context.vm, thread);
            bool returnValue;

            do
            {
                returnValue = val.InvokeMemberWithBooleanReturn("next");
                var value = val.GetProperty("value");
                yield return(value);
            } while (returnValue);
            context.Destroy();
        }
Beispiel #12
0
 public DuktapeValue(DuktapeContext context, uint refid)
 {
     this._context = context;
     this._refid   = refid;
 }
Beispiel #13
0
 public DuktapeArray(DuktapeContext context, uint refid)
     : base(context, refid)
 {
 }
Beispiel #14
0
 public DuktapeValue(IntPtr ctx, uint refid)
 {
     this._context = DuktapeVM.GetContext(ctx);
     this._refid   = refid;
 }
Beispiel #15
0
        private IEnumerator _InitializeStep(IDuktapeListener listener, int step)
        {
            var ctx = DuktapeDLL.duk_create_heap_default();

            _ctx = new DuktapeContext(this, ctx);
            DuktapeAux.duk_open(ctx);
            DuktapeVM.duk_open_module(ctx);
            DuktapeDLL.duk_unity_open(ctx);
            DuktapeDLL.duk_push_global_object(ctx);
            DuktapeJSBuiltins.reg(ctx);
            listener?.OnTypesBinding(this);
            var exportedTypes = this.GetType().Assembly.GetExportedTypes();
            var bindingTypes  = new List <Type>(exportedTypes.Length);
            var ctxAsArgs     = new object[] { ctx };

            for (int i = 0, size = exportedTypes.Length; i < size; i++)
            {
                var type = exportedTypes[i];
#if UNITY_EDITOR
                if (type.IsDefined(typeof(JSAutoRunAttribute), false))
                {
                    try
                    {
                        var run = type.GetMethod("Run", BindingFlags.Static | BindingFlags.Public);
                        if (run != null)
                        {
                            run.Invoke(null, null);
                        }
                    }
                    catch (Exception exception)
                    {
                        Debug.LogWarning($"JSAutoRun failed: {exception}");
                    }
                    continue;
                }
#endif
                var attributes = type.GetCustomAttributes(typeof(JSBindingAttribute), false);
                if (attributes.Length == 1)
                {
                    var jsBinding = attributes[0] as JSBindingAttribute;
                    if (jsBinding.Version == 0 || jsBinding.Version == VERSION)
                    {
                        bindingTypes.Add(type);
                    }
                    else
                    {
                        if (listener != null)
                        {
                            listener.OnBindingError(this, type);
                        }
                    }
                }
            }

            var numRegInvoked = bindingTypes.Count;
            for (var i = 0; i < numRegInvoked; ++i)
            {
                var type = bindingTypes[i];
                var reg  = type.GetMethod("reg");
                if (reg != null)
                {
                    reg.Invoke(null, ctxAsArgs);
                    if (listener != null)
                    {
                        listener.OnProgress(this, i, numRegInvoked);
                    }

                    if (i % step == 0)
                    {
                        yield return(null);
                    }
                }
            }
            if (listener != null)
            {
                listener.OnBinded(this, numRegInvoked);
            }
            // Debug.LogFormat("exported {0} classes", _exported.Count);

            // 设置导出类的继承链
            foreach (var kv in _exported)
            {
                var type     = kv.Key;
                var baseType = type.BaseType;
                if (baseType == null)
                {
                    // Debug.Log($"baseType is null, for {type}");
                    continue;
                }
                var fn = kv.Value;
                fn.PushPrototype(ctx);
                if (PushChainedPrototypeOf(ctx, baseType))
                {
                    // Debug.LogFormat($"set {type} super {baseType}");
                    DuktapeDLL.duk_set_prototype(ctx, -2);
                }
                else
                {
                    Debug.LogWarning($"fail to push prototype, for {type}: {baseType}");
                }
                DuktapeDLL.duk_pop(ctx);
            }

            DuktapeJSBuiltins.postreg(ctx);
            DuktapeDLL.duk_pop(ctx); // pop global

            _updateTimer = DuktapeRunner.SetInterval(this.OnUpdate, 100f);

            if (listener != null)
            {
                listener.OnLoaded(this);
            }
        }
Beispiel #16
0
 public static ObjectCache GetObjectCache(IntPtr ctx)
 {
     return(DuktapeContext.GetVM(ctx)?._objectCache);
 }
Beispiel #17
0
        // public static DuktapeContext GetContext(IntPtr ctx)
        // {
        //     return DuktapeContext.GetContext(ctx);
        // }

        public static DuktapeVM GetVM(IntPtr ctx)
        {
            return(DuktapeContext.GetVM(ctx));
        }
Beispiel #18
0
 public DuktapeValue(IntPtr ctx, uint refid, IntPtr heapPtr)
 {
     this._context = DuktapeVM.GetContext(ctx);
     this._refid   = refid;
     this._refPtr  = heapPtr;
 }