diff --git a/adapters/platforms/wechat/res/workers/ipc-worker.js b/adapters/platforms/wechat/res/workers/ipc-worker.js index ad768907..4015b62d 100644 --- a/adapters/platforms/wechat/res/workers/ipc-worker.js +++ b/adapters/platforms/wechat/res/workers/ipc-worker.js @@ -147,6 +147,7 @@ function _initFromWorker(id, meta) { CC_WORKER_AUDIO_SYSTEM, CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL, CC_WORKER_HTTP_REQUEST, + CC_WORKER_WEBSOCKET, ] = meta; for (const wrapper of wrappers) { @@ -164,6 +165,7 @@ function _initFromWorker(id, meta) { globalThis.CC_WORKER_AUDIO_SYSTEM = CC_WORKER_AUDIO_SYSTEM; globalThis.CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL = CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL; globalThis.CC_WORKER_HTTP_REQUEST = CC_WORKER_HTTP_REQUEST; + globalThis.CC_WORKER_WEBSOCKET = CC_WORKER_WEBSOCKET; _inited = true; if (_initCallback) _initCallback(); diff --git a/adapters/platforms/wechat/res/workers/macro.js b/adapters/platforms/wechat/res/workers/macro.js index 6a77bbc4..190d9dbd 100644 --- a/adapters/platforms/wechat/res/workers/macro.js +++ b/adapters/platforms/wechat/res/workers/macro.js @@ -21,5 +21,8 @@ globalThis.CC_WORKER_AUDIO_SYSTEM = null; // 是否启用 Worker 驱动 HTTP 请求 globalThis.CC_WORKER_HTTP_REQUEST = null; +// 是否启用 Worker 驱动 WebSocket +globalThis.CC_WORKER_WEBSOCKET = null; + // Worker 音频系统同步音频属性的间隔时间(单位:毫秒) globalThis.CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL = null; diff --git a/adapters/platforms/wechat/worker/index.js b/adapters/platforms/wechat/worker/index.js index c9ae1e18..6ddf44fe 100644 --- a/adapters/platforms/wechat/worker/index.js +++ b/adapters/platforms/wechat/worker/index.js @@ -16,6 +16,7 @@ module.exports = { CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL, CC_CUSTOM_WORKER, CC_WORKER_HTTP_REQUEST, + CC_WORKER_WEBSOCKET, CC_WORKER_SCHEDULER, CC_WORKER_FS_SYNC, CC_WORKER_SUB_PACKAGE, diff --git a/adapters/platforms/wechat/worker/ipc-main.js b/adapters/platforms/wechat/worker/ipc-main.js index eca9558c..96feb173 100644 --- a/adapters/platforms/wechat/worker/ipc-main.js +++ b/adapters/platforms/wechat/worker/ipc-main.js @@ -112,6 +112,7 @@ const ipcMain = { CC_WORKER_AUDIO_SYSTEM, CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL, CC_WORKER_HTTP_REQUEST, + CC_WORKER_WEBSOCKET, ]); }, diff --git a/adapters/platforms/wechat/worker/macro.js b/adapters/platforms/wechat/worker/macro.js index 5a7b12b9..88d735a0 100644 --- a/adapters/platforms/wechat/worker/macro.js +++ b/adapters/platforms/wechat/worker/macro.js @@ -35,6 +35,13 @@ if (!("CC_WORKER_HTTP_REQUEST" in globalThis)) { globalThis.CC_WORKER_HTTP_REQUEST = (isAndroid || isDevtools) && globalThis.CC_WORKER_HTTP_REQUEST; } +// 是否启用 Worker 驱动 WebSocket +if (!("CC_WORKER_WEBSOCKET" in globalThis)) { + globalThis.CC_WORKER_WEBSOCKET = false; + // NOTE 截止 2024.10.22,微信未修复 iOS、Windows、Mac 上仅文件系统 API 可以正常使用的问题 + globalThis.CC_WORKER_WEBSOCKET = (isAndroid || isDevtools) && globalThis.CC_WORKER_WEBSOCKET; +} + // 是否启用自定义 Worker if (!("CC_CUSTOM_WORKER" in globalThis)) { globalThis.CC_CUSTOM_WORKER = false; @@ -42,7 +49,7 @@ if (!("CC_CUSTOM_WORKER" in globalThis)) { // 是否启用 Worker if (!("CC_USE_WORKER" in globalThis)) { - globalThis.CC_USE_WORKER = (CC_WORKER_ASSET_PIPELINE || CC_WORKER_AUDIO_SYSTEM || CC_CUSTOM_WORKER || CC_WORKER_HTTP_REQUEST) && hasWorker && !isSubContext; + globalThis.CC_USE_WORKER = (CC_WORKER_ASSET_PIPELINE || CC_WORKER_AUDIO_SYSTEM || CC_CUSTOM_WORKER || CC_WORKER_HTTP_REQUEST || CC_WORKER_WEBSOCKET) && hasWorker && !isSubContext; } // 是否启用 Worker 调试模式 diff --git a/creator-sp.d.ts b/creator-sp.d.ts index 159977b0..1e600208 100644 --- a/creator-sp.d.ts +++ b/creator-sp.d.ts @@ -967,6 +967,11 @@ declare var CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL: number; */ declare var CC_WORKER_HTTP_REQUEST: boolean; +/** + * 是否启用 Worker 驱动 WebSocket + */ +declare var CC_WORKER_WEBSOCKET: boolean; + /** * 是否启用自定义 Worker */ diff --git a/extension/i18n/en.js b/extension/i18n/en.js index 61a7b80b..023ebfbd 100644 --- a/extension/i18n/en.js +++ b/extension/i18n/en.js @@ -64,6 +64,10 @@ module.exports = { 'thread_audio_system_desc': 'When enabled, time-consuming audio operations will be executed in a separate thread, reducing stuttering caused by audio API calls.', 'thread_audio_sync': 'Property Sync Interval (milliseconds)', 'thread_audio_sync_desc': 'How often the properties of audio instances (playback progress, total duration, etc.) are synchronized from the worker thread to the main thread. Too frequent updates may impact performance.', + 'thread_ws': 'Multi-threaded WebSocket', + 'thread_ws_desc': 'After enabling, the WebSocket will be executed in a separate thread, and custom data encoding/decoding is allowed. Due to the time-consuming data round-trip, please test in practice to see if there is an improvement in performance.', + 'thread_subpackage': 'Set Mini-Game subpackage', + 'thread_subpackage_desc': 'After enabling, the workers directory will be set as a mini-game subpackage, which will reduce the size of the main package but may affect startup performance. Please enable according to the situation.', 'thread_scheduler': 'Thread Communication Scheduler', 'thread_scheduler_desc': 'When enabled, multiple data communications will be bundled and sent together, which may reduce performance overhead caused by frequent communications.', 'thread_compile_custom_thread_menu': 'Recompile the multithreading extension', diff --git a/extension/i18n/zh.js b/extension/i18n/zh.js index 5a5edeb0..a191dd73 100644 --- a/extension/i18n/zh.js +++ b/extension/i18n/zh.js @@ -64,6 +64,10 @@ module.exports = { 'thread_audio_system_desc': '启用后将音频耗时操作移至线程中执行,减少由音频 API 调用导致的卡顿。', 'thread_audio_sync': '属性同步间隔(毫秒)', 'thread_audio_sync_desc': '间隔多久从 Worker 线程将音频实例的属性(播放进度、总时长等)同步到主线程,太频繁可能会影响性能。', + 'thread_ws': '多线程驱动 WebSocket', + 'thread_ws_desc': '启用后将 WebSocket 移至线程中执行,并且允许自定义数据编解码,由于存在数据往返的耗时,请实际测试对性能是否有提升。', + 'thread_subpackage': '设为小游戏子包', + 'thread_subpackage_desc': '启用后将 workers 目录设为小游戏子包,这会减少主包的大小,但可能影响启动性能,请视情况启用。', 'thread_scheduler': '线程通信调度器', 'thread_scheduler_desc': '启用后将多次数据通信打包发送,这可能会减少因通信次数带来的性能消耗。', 'thread_compile_custom_thread_menu': '重新编译多线程扩展', diff --git a/extension/main.js b/extension/main.js index 61120299..0d8cba4c 100644 --- a/extension/main.js +++ b/extension/main.js @@ -111,6 +111,8 @@ function getSettings() { CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL: getMacroIntegerValue(content, "CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL"), CC_CUSTOM_WORKER: getMacroBooleanValue(content, "CC_CUSTOM_WORKER"), CC_WORKER_HTTP_REQUEST: getMacroBooleanValue(content, "CC_WORKER_HTTP_REQUEST"), + CC_WORKER_WEBSOCKET: getMacroBooleanValue(content, "CC_WORKER_WEBSOCKET"), + CC_WORKER_SUB_PACKAGE: getMacroBooleanValue(content, "CC_WORKER_SUB_PACKAGE"), }; } } @@ -175,7 +177,7 @@ function checkAndModifyWorkerFiles() { const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, { encoding: "utf-8" })); // 是否启用 Worker - if (result.CC_WORKER_ASSET_PIPELINE || result.CC_WORKER_AUDIO_SYSTEM || result.CC_CUSTOM_WORKER || result.CC_WORKER_HTTP_REQUEST) { + if (result.CC_WORKER_ASSET_PIPELINE || result.CC_WORKER_AUDIO_SYSTEM || result.CC_CUSTOM_WORKER || result.CC_WORKER_HTTP_REQUEST || result.CC_WORKER_WEBSOCKET) { // 没有 Worker 目录与配置的话提醒用户重新安装 if (!(gameJson.workers && fs.existsSync(workerDir))) { Editor.error(t('thread_not_right_workers_dir')); @@ -183,6 +185,12 @@ function checkAndModifyWorkerFiles() { } else { Editor.warn(t('thread_need_delete_files')); } + + // 是否使用子包 + if (gameJson.workers) { + gameJson.workers.isSubpackage = result.CC_WORKER_SUB_PACKAGE; + fs.writeFileSync(gameJsonPath, JSON.stringify(gameJson, null, 2)); + } } } diff --git a/extension/panel/index.js b/extension/panel/index.js index a1bbb711..d096ed49 100644 --- a/extension/panel/index.js +++ b/extension/panel/index.js @@ -28,9 +28,6 @@ Editor.Panel.extend({ - - -
@@ -42,8 +39,17 @@ Editor.Panel.extend({ + + + + + + - + + + +
@@ -61,12 +67,16 @@ Editor.Panel.extend({ thread_custom_checkbox: '#tcc', thread_http: '#th', thread_http_checkbox: '#thc', + thread_ws: '#tw', + thread_ws_checkbox: '#twc', thread_audio_system: '#fs', thread_audio_system_checkbox: '#fsc', thread_audio_system_interval: '#fsi', thread_audio_system_interval_input: '#fsii', thread_scheduler: '#ts', thread_scheduler_checkbox: '#tsc', + thread_subpackage: '#tsp', + thread_subpackage_checkbox: '#tspc', }, ready() { @@ -87,6 +97,8 @@ Editor.Panel.extend({ this.$thread_audio_system_checkbox.checked = data.CC_WORKER_AUDIO_SYSTEM; this.$thread_audio_system_interval_input.value = data.CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL; this.$thread_http_checkbox.checked = data.CC_WORKER_HTTP_REQUEST; + this.$thread_ws_checkbox.checked = data.CC_WORKER_WEBSOCKET; + this.$thread_subpackage_checkbox.checked = data.CC_WORKER_SUB_PACKAGE; this.$thread_scheduler_checkbox.checked = data.CC_WORKER_SCHEDULER; this.$thread_debug_checkbox.addEventListener('change', () => { @@ -105,6 +117,14 @@ Editor.Panel.extend({ this.setSettings("CC_WORKER_HTTP_REQUEST", this.$thread_http_checkbox.checked); }); + this.$thread_ws_checkbox.addEventListener('change', () => { + this.setSettings("CC_WORKER_WEBSOCKET", this.$thread_ws_checkbox.checked); + }); + + this.$thread_subpackage_checkbox.addEventListener('change', () => { + this.setSettings("CC_WORKER_SUB_PACKAGE", this.$thread_subpackage_checkbox.checked); + }); + const onAudioSystemEnableChange = (enabled) => { this.$thread_audio_system_interval_input.disabled = !enabled; }; diff --git a/extension/templates/2.4.13/2.3.0/worker/creator-worker.d.ts b/extension/templates/2.4.13/2.3.0/worker/creator-worker.d.ts index 726c976d..f21ad769 100644 --- a/extension/templates/2.4.13/2.3.0/worker/creator-worker.d.ts +++ b/extension/templates/2.4.13/2.3.0/worker/creator-worker.d.ts @@ -74,3 +74,8 @@ declare var CC_WORKER_AUDIO_SYSTEM_SYNC_INTERVAL: number; * 是否启用 Worker 驱动 HTTP 请求 */ declare var CC_WORKER_HTTP_REQUEST: boolean; + +/** + * 是否启用 Worker 驱动 WebSocket + */ +declare var CC_WORKER_WEBSOCKET: boolean;