first
This commit is contained in:
359
extensions/app/assets/base/BaseManager.ts
Normal file
359
extensions/app/assets/base/BaseManager.ts
Normal file
@@ -0,0 +1,359 @@
|
||||
import { AssetManager, Component, EventTarget, Prefab, Widget, _decorator, error, instantiate, js, path, warn } from 'cc';
|
||||
import { DEBUG, DEV, EDITOR } from 'cc/env';
|
||||
import Core from '../Core';
|
||||
import { Logger } from '../lib/logger/logger';
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
const UserManagerPath = 'UserManager';
|
||||
const DontRewriteFuns = ['emit', 'on', 'once', 'off', 'targetOff'];
|
||||
|
||||
const uuid = new class UUID {
|
||||
private index = 0;
|
||||
|
||||
public create(): string {
|
||||
if (this.index++ > 10000000) {
|
||||
this.index = 0;
|
||||
}
|
||||
return `${Date.now()}-${this.index}`;
|
||||
}
|
||||
};
|
||||
|
||||
const loadBegin = Logger.create('log', '#32cd32', DEV ? '[BaseManager] 下载开始' : '[BaseManager] [下载开始]');
|
||||
|
||||
const loadFinish = Logger.create('log', '#00ae9d', DEV ? '[BaseManager] 下载完成' : '[BaseManager] [下载完成]');
|
||||
|
||||
const loadError = Logger.create('log', '#ff4757', DEV ? '[BaseManager] 下载失败' : '[BaseManager] [下载失败]');
|
||||
|
||||
const initBegin = Logger.create('log', '#3e4145', DEV ? '[BaseManager] 初始化开始' : '[BaseManager] [初始化开始]');
|
||||
|
||||
const initFinish = Logger.create('log', '#008080', DEV ? '[BaseManager] 初始化完成' : '[BaseManager] [初始化完成]');
|
||||
|
||||
@ccclass('BaseManager')
|
||||
export default class BaseManager extends Component {
|
||||
// 事件管理器
|
||||
private _base_event: EventTarget = new EventTarget();
|
||||
|
||||
// manager名字
|
||||
private _base_manager_name: string = js.getClassName(this);
|
||||
public get managerName() {
|
||||
return this._base_manager_name;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (EDITOR) {
|
||||
DontRewriteFuns.forEach((funName) => {
|
||||
if (BaseManager.prototype[funName] !== this[funName]) {
|
||||
warn(`[${this._base_manager_name}] 不应该重写父类方法{${funName}}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this._base_manager_name !== 'Manager' && this._base_manager_name.slice(-7) === 'Manager') {
|
||||
const managerName = this._base_manager_name.slice(0, - 7);
|
||||
Core.inst.Manager[managerName] = this.constructor;
|
||||
Core.inst.manager[managerName.toLowerCase()] = this;
|
||||
} else if (EDITOR) {
|
||||
error(`[${this._base_manager_name}] manager命名错误(应为 xxxxManager 以Manager结尾)`);
|
||||
} else if (DEBUG) {
|
||||
error(`[${this._base_manager_name}] manager命名错误(应为 xxxxManager 以Manager结尾)`);
|
||||
}
|
||||
}
|
||||
|
||||
// 用来初始化组件或节点的一些属性,当该组件被第一次添加到节点上或用户点击了它的 Reset 菜单时调用。这个回调只会在编辑器下调用。
|
||||
resetInEditor() {
|
||||
const widget = this.node.getComponent(Widget) || this.node.addComponent(Widget);
|
||||
widget.isAlignBottom = true;
|
||||
widget.isAlignLeft = true;
|
||||
widget.isAlignRight = true;
|
||||
widget.isAlignTop = true;
|
||||
widget.top = 0;
|
||||
widget.left = 0;
|
||||
widget.right = 0;
|
||||
widget.bottom = 0;
|
||||
widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* [无序] 自身初始化完成, init执行完毕后被调用
|
||||
*/
|
||||
protected onInited() {
|
||||
}
|
||||
|
||||
/**
|
||||
* [无序] 所有manager初始化完成
|
||||
*/
|
||||
protected onFinished() {
|
||||
}
|
||||
|
||||
/**
|
||||
* [无序] 初始化manager,在初始化完成后,调用finish方法
|
||||
* @param {Function} finish
|
||||
*/
|
||||
protected init(finish?: Function) {
|
||||
finish && finish();
|
||||
}
|
||||
|
||||
protected createUUID() {
|
||||
return uuid.create();
|
||||
}
|
||||
|
||||
/**打印日志 */
|
||||
protected get log() {
|
||||
if (DEV) {
|
||||
return window.console.log.bind(window.console,
|
||||
'%c %s %c %s ',
|
||||
'background:#4169e1; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #4169e1; color: #fff; font-weight: normal;',
|
||||
`[${this._base_manager_name}] LOG ${new Date().toLocaleString()}`,
|
||||
'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #4169e1; color: #4169e1; font-weight: normal;'
|
||||
);
|
||||
}
|
||||
return window.console.log.bind(window.console,
|
||||
`[${this._base_manager_name}] [LOG] [${new Date().toLocaleString()}]`,
|
||||
);
|
||||
}
|
||||
|
||||
/**打印警告 */
|
||||
protected get warn() {
|
||||
if (DEV) {
|
||||
return window.console.warn.bind(window.console,
|
||||
'%c %s %c %s ',
|
||||
'background:#ff7f50; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #ff7f50; color: #fff; font-weight: normal;',
|
||||
`[${this._base_manager_name}] WARN ${new Date().toLocaleString()}`,
|
||||
'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #ff7f50; color: #ff7f50; font-weight: normal;'
|
||||
);
|
||||
}
|
||||
return window.console.warn.bind(window.console,
|
||||
`[${this._base_manager_name}] [WARN] [${new Date().toLocaleString()}]`,
|
||||
);
|
||||
}
|
||||
|
||||
/**打印错误 */
|
||||
protected get error() {
|
||||
if (DEV) {
|
||||
return window.console.error.bind(window.console,
|
||||
'%c %s %c %s ',
|
||||
'background:#ff4757; padding: 2px; border-radius: 5px 0 0 5px; border: 1px solid #ff4757; color: #fff; font-weight: normal;',
|
||||
`[${this._base_manager_name}] ERROR ${new Date().toLocaleString()}`,
|
||||
'background:#ffffff ; padding: 2px; border-radius: 0 5px 5px 0; border: 1px solid #ff4757; color: #ff4757; font-weight: normal;'
|
||||
);
|
||||
}
|
||||
return window.console.error.bind(window.console,
|
||||
`[${this._base_manager_name}] [ERROR] [${new Date().toLocaleString()}]`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* [系统内置] 事件分发
|
||||
*/
|
||||
public emit(event: string | number, ...data: any[]) {
|
||||
this._base_event.emit(event as any, ...data);
|
||||
}
|
||||
|
||||
/**
|
||||
* [系统内置] 事件监听
|
||||
*/
|
||||
public on(event: string | number, cb: (...any: any[]) => void, target?: any) {
|
||||
this._base_event.on(event as any, cb, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* [系统内置] 事件监听
|
||||
*/
|
||||
public once(event: string | number, cb: (...any: any[]) => void, target?: any) {
|
||||
this._base_event.once(event as any, cb, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* [系统内置] 事件移除监听
|
||||
*/
|
||||
public off(event: string | number, cb?: (...any: any[]) => void, target?: any) {
|
||||
this._base_event.off(event as any, cb, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* [系统内置] 事件移除监听
|
||||
*/
|
||||
public targetOff(target: any) {
|
||||
this._base_event.targetOff(target);
|
||||
}
|
||||
|
||||
/***********************************静态***********************************/
|
||||
/**
|
||||
* 框架内置Manager的数量
|
||||
* @private
|
||||
*/
|
||||
public static get sysMgrCount() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得初始化资源的数量(包括sysMgrCount)
|
||||
* @private
|
||||
*/
|
||||
public static getTotalAssetNum(bundle: AssetManager.Bundle) {
|
||||
let count = this.sysMgrCount;
|
||||
|
||||
if (!bundle) return count;
|
||||
|
||||
const array = bundle.getDirWithPath('/', Prefab) as { uuid: string, path: string, ctor: Function }[];
|
||||
|
||||
array.forEach(function (item) {
|
||||
if (item.path.endsWith('Manager')) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得初始化资源的数量
|
||||
* @private
|
||||
*/
|
||||
public static getUserAssetUrls(bundle: AssetManager.Bundle) {
|
||||
const pathArr: string[] = [];
|
||||
|
||||
if (!bundle) return pathArr;
|
||||
|
||||
const array = bundle.getDirWithPath('/', Prefab) as { uuid: string, path: string, ctor: Function }[];
|
||||
|
||||
array.forEach(function (item) {
|
||||
if (item.path.endsWith('Manager')) {
|
||||
pathArr.push(item.path);
|
||||
}
|
||||
});
|
||||
|
||||
return pathArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态方法,初始化manager,该方法必须在场景初始化完毕之后调用
|
||||
* @private
|
||||
*/
|
||||
public static init(
|
||||
bundle: AssetManager.Bundle,
|
||||
progress: (completeAsset: Number, totalAsset: Number) => any,
|
||||
complete: (totalAsset: Number) => any) {
|
||||
const urls = this.getUserAssetUrls(bundle);
|
||||
|
||||
const totalAsset = urls.length + this.sysMgrCount;
|
||||
let completeAsset = 0;
|
||||
|
||||
const onProgress = function (next: Function, manager: BaseManager) {
|
||||
if (DEBUG) {
|
||||
const startTime = window?.performance?.now ? performance.now() : Date.now();
|
||||
initBegin(manager.managerName);
|
||||
return function () {
|
||||
manager.onInited();
|
||||
if (DEBUG) {
|
||||
const endTime = window?.performance?.now ? performance.now() : Date.now();
|
||||
initFinish(`${manager.managerName} 耗时:${(endTime - startTime).toFixed(6)} ms`);
|
||||
}
|
||||
progress && progress(++completeAsset, totalAsset);
|
||||
next();
|
||||
};
|
||||
}
|
||||
return function () {
|
||||
manager.onInited();
|
||||
progress && progress(++completeAsset, totalAsset);
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
// 用户manager(动态添加)
|
||||
const userMgrList: BaseManager[] = [];
|
||||
// 系统manager(静态内置)
|
||||
const sysMgrList: BaseManager[] = [Core.inst.manager.event, Core.inst.manager.timer, Core.inst.manager.loader, Core.inst.manager.ui, Core.inst.manager.sound] as any as BaseManager[];
|
||||
|
||||
// 初始化系统manager
|
||||
const initSysMgrTask = Core.inst.lib.task.createASync();
|
||||
sysMgrList.forEach(function (manager: BaseManager) {
|
||||
initSysMgrTask.add(function (next) {
|
||||
manager.init(onProgress(next, manager));
|
||||
});
|
||||
});
|
||||
|
||||
// 加载用户manager
|
||||
const loadUserMgrTask = Core.inst.lib.task.createASync();
|
||||
const UserManagerRoot = Core.inst.manager.ui.root.getChildByPath(UserManagerPath);
|
||||
urls.forEach(function (url) {
|
||||
loadUserMgrTask.add(function (next, retry) {
|
||||
if (DEBUG) {
|
||||
const managerName = path.basename(url);
|
||||
const startTime = window?.performance?.now ? performance.now() : Date.now();
|
||||
loadBegin(managerName);
|
||||
bundle.load(url, Prefab, function (err, prefab: Prefab) {
|
||||
if (err || !prefab) {
|
||||
loadError(managerName, '重试...');
|
||||
retry(1);
|
||||
} else {
|
||||
const endTime = window?.performance?.now ? performance.now() : Date.now();
|
||||
loadFinish(`${managerName} 耗时:${(endTime - startTime).toFixed(6)} ms`);
|
||||
const node = instantiate(prefab);
|
||||
node.parent = UserManagerRoot;
|
||||
node.active = true;
|
||||
userMgrList.push(node.getComponent(BaseManager));
|
||||
next();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
bundle.load(url, Prefab, function (err, prefab: Prefab) {
|
||||
if (err || !prefab) {
|
||||
loadError(path.basename(url), '重试...');
|
||||
retry(1);
|
||||
} else {
|
||||
const node = instantiate(prefab);
|
||||
node.parent = UserManagerRoot;
|
||||
node.active = true;
|
||||
userMgrList.push(node.getComponent(BaseManager));
|
||||
next();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Core.inst.lib.task.createAny()
|
||||
.add([
|
||||
next => initSysMgrTask.start(next),
|
||||
next => loadUserMgrTask.start(next),
|
||||
])
|
||||
.add(function (next) {
|
||||
Core.emit(Core.EventType.EVENT_SYS_MANAGER_INITED);
|
||||
next();
|
||||
})
|
||||
.add(function (next) {
|
||||
// 初始化用户manager
|
||||
const initUserMgrTask = Core.inst.lib.task.createASync();
|
||||
userMgrList.forEach(manager => {
|
||||
initUserMgrTask.add(function (next) {
|
||||
manager.init(onProgress(next, manager));
|
||||
});
|
||||
});
|
||||
initUserMgrTask.start(next);
|
||||
})
|
||||
.add(function (next) {
|
||||
Core.emit(Core.EventType.EVENT_USER_MANAGER_INITED);
|
||||
Core.emit(Core.EventType.EVENT_MANAGER_INITED);
|
||||
next();
|
||||
})
|
||||
.add(function (next) {
|
||||
// 所有manager初始化完成后,触发回调
|
||||
sysMgrList.forEach(function (manager) {
|
||||
manager.onFinished();
|
||||
});
|
||||
userMgrList.forEach(function (manager) {
|
||||
manager.onFinished();
|
||||
});
|
||||
next();
|
||||
})
|
||||
.start(function () {
|
||||
Core.emit(Core.EventType.EVENT_MANAGER_FINISHED);
|
||||
complete && complete(totalAsset);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user