예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
            }
        }