public void Destroy() { lock (this) { if (!_isValid) { return; } _isValid = false; try { OnDestroy?.Invoke(this); } catch (Exception e) { _logger?.WriteException(e); } } _timerManager.Destroy(); _objectCache.Destroy(); _typeDB.Destroy(); GC.Collect(); GC.WaitForPendingFinalizers(); ExecutePendingActions(); // _rwlock.EnterWriteLock(); for (int i = 0, count = _contextRefs.Count; i < count; i++) { var contextRef = _contextRefs[i]; contextRef.target.Destroy(); } _contextRefs.Clear(); _mainContext = null; // _rwlock.ExitWriteLock(); if (_asyncManager != null) { _asyncManager.Destroy(); _asyncManager = null; } JSApi.JS_FreeRuntime(_rt); var id = _runtimeId; _runtimeId = -1; _rt = JSRuntime.Null; try { OnAfterDestroy?.Invoke(id); } catch (Exception e) { _logger?.WriteException(e); } }
private void RaiseScriptReloadingEvent_nothrow(ScriptContext context, string resolved_id) { try { OnScriptReloading?.Invoke(context, resolved_id); context.RaiseScriptReloadingEvent_throw(resolved_id); } catch (Exception exception) { _logger?.WriteException(exception); } }
private void InvokeTimers() { var cachedSize = _tcache1.Count; if (cachedSize > 0) { for (var i = 0; i < cachedSize; ++i) { var timer = _tcache1[i]; var handler = timer.action; if (timer.slot != null) { timer.slot.Remove(timer); timer.slot = null; } // UnityEngine.Debug.LogError($"[timer#{timer.id}] active"); if (!timer.deleted && handler != null) { try { handler.Invoke(); } catch (Exception exception) { _logger?.WriteException(exception); // UnityEngine.Debug.LogErrorFormat("Scheduler Exception: {0}", exception); } } if (!timer.deleted) { if (timer.once) { timer.deleted = true; timer.Cleanup(); _timeHandles.Remove(timer.id); _recycle.Add(timer); } else { timer.deadline = timer.delay + _elapsed; Rearrange(timer); } } } // 回收 for (int i = 0, size = _recycle.Count; i < size; ++i) { var timer = _recycle[i]; if (_pool.Count < _poolCapacity) { _pool.Add(timer); } } _recycle.Clear(); _tcache1.Clear(); } }
// this method will be marked as private in the future public void Initialize(IFileSystem fileSystem, IPathResolver resolver, IAsyncManager asyncManager, IScriptLogger logger, IO.IByteBufferAllocator byteBufferAllocator, IBinder binder) { if (fileSystem == null) { throw new NullReferenceException(nameof(fileSystem)); } asyncManager.Initialize(_mainThreadId); _isValid = true; _isRunning = true; _logger = logger; // _rwlock = new ReaderWriterLockSlim(); _rt = JSApi.JS_NewRuntime(); JSApi.JS_SetHostPromiseRejectionTracker(_rt, JSApi.PromiseRejectionTracker, IntPtr.Zero); #if UNITY_EDITOR JSApi.JS_SetInterruptHandler(_rt, _InterruptHandler, IntPtr.Zero); #else if (isWorker) { JSApi.JS_SetInterruptHandler(_rt, _InterruptHandler, IntPtr.Zero); } #endif JSApi.JS_SetRuntimeOpaque(_rt, (IntPtr)_runtimeId); JSApi.JS_SetModuleLoaderFunc(_rt, module_normalize, module_loader, IntPtr.Zero); CreateContext(); JSApi.JS_NewClass(_rt, JSApi.JSB_GetBridgeClassID(), "CSharpClass", JSApi.class_finalizer); _pathResolver = resolver; _asyncManager = asyncManager; _byteBufferAllocator = byteBufferAllocator; _autorelease = new Utils.AutoReleasePool(); _fileSystem = fileSystem; _objectCache = new ObjectCache(_logger); _timerManager = new TimerManager(_logger); _typeDB = new TypeDB(this, _mainContext); #if !JSB_UNITYLESS _typeDB.AddType(typeof(Unity.JSBehaviour), JSApi.JS_UNDEFINED); #endif #if UNITY_EDITOR _typeDB.AddType(Values.FindType("QuickJS.Unity.JSEditorWindow"), JSApi.JS_UNDEFINED); _typeDB.AddType(Values.FindType("QuickJS.Unity.JSBehaviourInspector"), JSApi.JS_UNDEFINED); #endif // await Task.Run(() => runner.OnBind(this, register)); try { binder?.Bind(this); } catch (Exception exception) { _logger?.WriteException(exception); } var register = new TypeRegister(_mainContext); if (!_isWorker) { JSWorker.Bind(register); } TimerManager.Bind(register); extraBinding?.Invoke(this, register); register.Finish(); AddStaticModule("jsb", ScriptContext.Bind); FindModuleResolver <StaticModuleResolver>().Warmup(_mainContext); _isInitialized = true; }