mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-10-09 16:55:23 +00:00
[adapters] 优化多线程特性文件结构,增加部分多线程音频系统代码,支持 Worker 子包特性(默认不开启),修复 Devtools 下强制不启用 Worker 问题
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
const { init: initWorker, onInited: onWorkerInited } = require('./worker_adapter/index.js');
|
||||
require('adapter-js-path');
|
||||
initWorker();
|
||||
__globalAdapter.init();
|
||||
require('cocos2d-js-path');
|
||||
require('physics-js-path');
|
||||
@@ -19,8 +17,6 @@ if (cc.sys.platform !== cc.sys.WECHAT_GAME_SUB) {
|
||||
cc.macro.CLEANUP_IMAGE_CACHE = true;
|
||||
}
|
||||
|
||||
const t = Date.now();
|
||||
onWorkerInited(() => {
|
||||
console.log("worker waiting time:", Date.now() - t);
|
||||
__globalAdapter.onInited(() => {
|
||||
window.boot();
|
||||
});
|
||||
|
@@ -1,24 +0,0 @@
|
||||
var assetManagerWorkerAdapter = {
|
||||
// 返回当前 cc.assetManager.bundles 的 [name, base]
|
||||
getAllBundles(args, cmdId, callback) {
|
||||
var bundles = [];
|
||||
cc.assetManager.bundles.forEach((v, k) => {
|
||||
bundles.push([v.name, v.base]);
|
||||
});
|
||||
callback(cmdId, [bundles]);
|
||||
},
|
||||
// 删除缓存文件记录
|
||||
removeCachedFiles(args, cmdId, callback) {
|
||||
const deletedFiles = args[0];
|
||||
for (let i = 0, l = deletedFiles.length; i < l; i++) {
|
||||
cc.assetManager.cacheManager.cachedFiles.remove(deletedFiles[i]);
|
||||
}
|
||||
},
|
||||
// 添加缓存文件记录
|
||||
addCachedFiles(args, cmdId, callback) {
|
||||
const [id, cacheBundleRoot, localPath, time] = args[0];
|
||||
cc.assetManager.cacheManager.cachedFiles.add(id, { bundle: cacheBundleRoot, url: localPath, lastTime: time });
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = assetManagerWorkerAdapter;
|
@@ -1,4 +0,0 @@
|
||||
if (CC_WORKER_ASSET_PIPELINE) {
|
||||
const assetManagerWorkerAdapter = require("./asset-manager.js");
|
||||
ipcMain.registerHandler("assetManager", assetManagerWorkerAdapter);
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
require("./macro.js");
|
||||
require("./ipc-main.js");
|
||||
require("./handlers.js");
|
||||
|
||||
let inited = false;
|
||||
let _callback = null;
|
||||
|
||||
module.exports = {
|
||||
init() {
|
||||
if (CC_USE_WORKER) {
|
||||
var t = Date.now();
|
||||
ipcMain.init(() => {
|
||||
console.log("worker init cost:", Date.now() - t);
|
||||
console.log("worker settings:", {
|
||||
CC_USE_WORKER,
|
||||
CC_WORKER_DEBUG,
|
||||
CC_WORKER_ASSET_PIPELINE,
|
||||
CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD,
|
||||
CC_WORKER_SCHEDULER,
|
||||
CC_WORKER_FS_SYNC,
|
||||
});
|
||||
inited = true;
|
||||
_callback && _callback();
|
||||
_callback = null;
|
||||
});
|
||||
} else {
|
||||
inited = true;
|
||||
_callback && _callback();
|
||||
_callback = null;
|
||||
}
|
||||
},
|
||||
onInited(callback) {
|
||||
if (inited) {
|
||||
callback();
|
||||
} else {
|
||||
_callback = callback;
|
||||
}
|
||||
},
|
||||
};
|
@@ -1,215 +0,0 @@
|
||||
const ipcMain = {
|
||||
worker: null,
|
||||
|
||||
cmdId: 0,
|
||||
|
||||
callbacks: {},
|
||||
|
||||
_cmd: 0,
|
||||
|
||||
handlers: {},
|
||||
|
||||
_inited: false,
|
||||
|
||||
_initCallback: null,
|
||||
|
||||
init(callback) {
|
||||
this._initCallback = callback;
|
||||
|
||||
// NOTE { useExperimentalWorker: true } 会让有状态的 Worker 处理很复杂,暂时不使用
|
||||
this.worker = wx.createWorker("workers/index.js");
|
||||
|
||||
this.worker.onMessage(
|
||||
CC_WORKER_SCHEDULER
|
||||
? msgs => {
|
||||
for (let index = 0; index < msgs.length; index++) {
|
||||
const msg = msgs[index];
|
||||
this._handleWorkerMessage(msg);
|
||||
}
|
||||
}
|
||||
: this._handleWorkerMessage.bind(this)
|
||||
);
|
||||
|
||||
if (CC_WORKER_SCHEDULER) {
|
||||
sendScheduler.init(this);
|
||||
}
|
||||
|
||||
this._init();
|
||||
},
|
||||
|
||||
_handleWorkerMessage(msg) {
|
||||
// 格式:[id, cmd, [args] | null]
|
||||
// 如果 cmd 是正数,则是返回到主线程的 Callback
|
||||
// 反之,是 Worker 的调用
|
||||
|
||||
// [-, 0, handlers] 为初始化调用
|
||||
|
||||
const id = msg[0];
|
||||
const cmd = msg[1];
|
||||
const args = msg[2];
|
||||
|
||||
if (cmd > 0) {
|
||||
if (CC_WORKER_DEBUG) {
|
||||
console.log("main thread recv callback:", msg);
|
||||
}
|
||||
const callback = this.callbacks[id];
|
||||
if (callback) {
|
||||
callback(args);
|
||||
delete this.callbacks[id];
|
||||
}
|
||||
} else if (cmd < 0) {
|
||||
const handler = this.handlers[cmd];
|
||||
|
||||
if (handler) {
|
||||
const { func, name, key, callback } = handler;
|
||||
|
||||
if (CC_WORKER_DEBUG) {
|
||||
console.log(`main thread recv call (${name}.${key}):`, msg);
|
||||
}
|
||||
|
||||
func(args, id, callback);
|
||||
} else {
|
||||
console.error("main thread recv unknown call:", msg);
|
||||
}
|
||||
} else {
|
||||
if (CC_WORKER_DEBUG) {
|
||||
console.log("main thread recv init:", msg);
|
||||
}
|
||||
this._initFromWorker(args);
|
||||
}
|
||||
},
|
||||
|
||||
_init() {
|
||||
const _handlers = [];
|
||||
for (const cmd in this.handlers) {
|
||||
const { name, key } = this.handlers[cmd];
|
||||
_handlers.push({ name, cmd: Number(cmd), key });
|
||||
}
|
||||
|
||||
this.callToWorker(0, [
|
||||
_handlers,
|
||||
CC_WORKER_FS_SYNC,
|
||||
CC_WORKER_ASSET_PIPELINE,
|
||||
CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD,
|
||||
]);
|
||||
},
|
||||
|
||||
_initFromWorker(wrappers) {
|
||||
for (const wrapper of wrappers) {
|
||||
const { name, key, cmd } = wrapper;
|
||||
if (!worker[name]) {
|
||||
worker[name] = {};
|
||||
}
|
||||
worker[name][key] = (args, callback) => {
|
||||
this.callToWorker(cmd, args, callback);
|
||||
};
|
||||
}
|
||||
|
||||
this._inited = true;
|
||||
if (this._initCallback) this._initCallback();
|
||||
},
|
||||
|
||||
callbackToWorker(id, cmd, args) {
|
||||
const msg = [id, cmd, args];
|
||||
|
||||
if (CC_WORKER_DEBUG) {
|
||||
console.log("main thread send callback:", msg);
|
||||
}
|
||||
|
||||
if (CC_WORKER_SCHEDULER) {
|
||||
sendScheduler.send(msg);
|
||||
} else {
|
||||
this.worker.postMessage(msg);
|
||||
}
|
||||
},
|
||||
|
||||
callToWorker(cmd, args, callback) {
|
||||
const id = ++this.cmdId;
|
||||
|
||||
if (callback) {
|
||||
this.callbacks[id] = callback;
|
||||
}
|
||||
|
||||
const msg = [id, cmd, args];
|
||||
|
||||
if (CC_WORKER_DEBUG) {
|
||||
console.log("main thread send call:", msg);
|
||||
}
|
||||
|
||||
if (CC_WORKER_SCHEDULER) {
|
||||
sendScheduler.send(msg);
|
||||
} else {
|
||||
this.worker.postMessage(msg);
|
||||
}
|
||||
},
|
||||
|
||||
registerHandler(name, obj) {
|
||||
const descs = Object.getOwnPropertyDescriptors(obj);
|
||||
|
||||
for (const key in descs) {
|
||||
const desc = descs[key];
|
||||
|
||||
if (typeof desc.value === "function") {
|
||||
const cmd = ++this._cmd;
|
||||
this.handlers[cmd] = {
|
||||
name,
|
||||
key,
|
||||
func: obj[key].bind(obj),
|
||||
callback: (id, args) => this.callbackToWorker(id, cmd, args),
|
||||
};
|
||||
} else {
|
||||
// getter/setter
|
||||
const cmd1 = ++this._cmd;
|
||||
this.handlers[cmd1] = {
|
||||
name,
|
||||
key: "get_" + key,
|
||||
func: (args, id, callback) => {
|
||||
this.callbackToWorker(id, cmd1, [obj[key]]);
|
||||
},
|
||||
callback: null,
|
||||
};
|
||||
const cmd2 = ++this._cmd;
|
||||
this.handlers[cmd2] = {
|
||||
name,
|
||||
key: "set_" + key,
|
||||
func: (args, id, callback) => {
|
||||
obj[key] = args[0];
|
||||
}
|
||||
};
|
||||
const cmd3 = ++this._cmd;
|
||||
this.handlers[cmd3] = {
|
||||
name,
|
||||
key: "write_" + key,
|
||||
func: (args, id, callback) => {
|
||||
obj[key] = args[0];
|
||||
this.callbackToWorker(id, cmd3, null);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const sendScheduler = {
|
||||
queue: [],
|
||||
ipc: null,
|
||||
|
||||
init(ipc) {
|
||||
this.ipc = ipc;
|
||||
setInterval(() => {
|
||||
if (this.queue.length > 0) {
|
||||
this.ipc.worker.postMessage(this.queue);
|
||||
this.queue = [];
|
||||
}
|
||||
}, 0);
|
||||
},
|
||||
|
||||
send(msg) {
|
||||
this.queue.push(msg);
|
||||
},
|
||||
};
|
||||
|
||||
const worker = {};
|
||||
|
||||
globalThis.ipcMain = ipcMain;
|
||||
globalThis.worker = worker;
|
@@ -1,29 +0,0 @@
|
||||
const isSubContext = wx.getOpenDataContext === undefined;
|
||||
const sysinfo = wx.getSystemInfoSync();
|
||||
const platform = sysinfo.platform.toLowerCase();
|
||||
const isAndroid = platform === "android";
|
||||
const sdkVersion = sysinfo.SDKVersion.split('.').map(Number);
|
||||
// >= 2.20.2
|
||||
const hasWorker = sdkVersion[0] > 2 || (sdkVersion[0] === 2 && (sdkVersion[1] > 20 || (sdkVersion[1] === 20 && sdkVersion[2] >= 2)));
|
||||
|
||||
// 是否启用 Worker 驱动资源管线(下载、缓存)
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE = false;
|
||||
|
||||
// 是否启用 Worker 驱动资源管线(加载)
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD = false;
|
||||
|
||||
// NOTE 截止 2024.10.22,微信未修复 iOS、Windows、Mac 上仅文件系统 API 可以正常使用的问题
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE = isAndroid && globalThis.CC_WORKER_ASSET_PIPELINE;
|
||||
|
||||
// 是否启用 Worker
|
||||
globalThis.CC_USE_WORKER = (CC_WORKER_ASSET_PIPELINE) && hasWorker && !isSubContext;
|
||||
|
||||
// 是否启用 Worker 调试模式
|
||||
globalThis.CC_WORKER_DEBUG = false;
|
||||
|
||||
// 是否启用 Worker 调度模式,这也许能减少通信次数带来的性能消耗(必须一致)
|
||||
globalThis.CC_WORKER_SCHEDULER = true;
|
||||
|
||||
// 是否启用 Worker 使用同步版本的文件系统 API
|
||||
// NOTE: IOS 不支持 async 文件系统 API,Android 不支持部分 sync 文件系统 API,其余系统暂不确定
|
||||
globalThis.CC_WORKER_FS_SYNC = !isAndroid;
|
9
adapters/platforms/wechat/res/workers/audio-worker.js
Normal file
9
adapters/platforms/wechat/res/workers/audio-worker.js
Normal file
@@ -0,0 +1,9 @@
|
||||
var audio_worker = {
|
||||
map: {},
|
||||
create(callback, sn) {
|
||||
this.map[sn] = worker.createInnerAudioContext();
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = audio_worker;
|
@@ -4,3 +4,8 @@ if (globalThis.CC_WORKER_ASSET_PIPELINE) {
|
||||
const cacheManager = require("./cache-manager-worker.js");
|
||||
registerHandler("cacheManager", cacheManager);
|
||||
}
|
||||
|
||||
if (globalThis.CC_WORKER_AUDIO_SYSTEM) {
|
||||
const audio = require("./audio-worker.js");
|
||||
registerHandler("audio", audio);
|
||||
}
|
||||
|
@@ -144,7 +144,7 @@ function _initFromWorker(id, meta) {
|
||||
wrappers,
|
||||
CC_WORKER_FS_SYNC,
|
||||
CC_WORKER_ASSET_PIPELINE,
|
||||
CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD,
|
||||
CC_WORKER_AUDIO_SYSTEM,
|
||||
] = meta;
|
||||
|
||||
for (const wrapper of wrappers) {
|
||||
@@ -159,7 +159,7 @@ function _initFromWorker(id, meta) {
|
||||
|
||||
globalThis.CC_WORKER_FS_SYNC = CC_WORKER_FS_SYNC;
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE = CC_WORKER_ASSET_PIPELINE;
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD = CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD;
|
||||
globalThis.CC_WORKER_AUDIO_SYSTEM = CC_WORKER_AUDIO_SYSTEM;
|
||||
|
||||
_inited = true;
|
||||
if (_initCallback) _initCallback();
|
||||
|
@@ -9,8 +9,8 @@ globalThis.CC_WORKER_DEBUG = false;
|
||||
// 是否启用 Worker 使用同步版本的文件系统 API
|
||||
globalThis.CC_WORKER_FS_SYNC = null;
|
||||
|
||||
// 是否启用 Worker 驱动资源管线(下载、缓存)
|
||||
// 是否启用 Worker 驱动资源管线
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE = null;
|
||||
|
||||
// 是否启用 Worker 驱动资源管线(加载)
|
||||
globalThis.CC_WORKER_ASSET_PIPELINE_INCLUDE_LOAD = null;
|
||||
// 是否启用 Worker 驱动音频系统
|
||||
globalThis.CC_WORKER_AUDIO_SYSTEM = null;
|
||||
|
Reference in New Issue
Block a user