mirror of
https://github.com/unanmed/HumanBreak.git
synced 2026-11-09 14:24:30 +08:00
refactor: 地图渲染器改为与 LayerState 绑定
This commit is contained in:
1 parent
6ae0d6ca5f
commit
ebaa35ea5b
17 files changed
+564
-387
No files matched your search
@@ -0,0 +1,82 @@
|
||||
import { logger } from './logger';
|
||||
import { IHookable, IHookBase, IHookController, IHookObject } from './types';
|
||||
|
||||
export abstract class Hookable<
|
||||
H extends IHookBase = IHookBase,
|
||||
C extends IHookController<H> = IHookController<H>
|
||||
> implements IHookable<H, C>
|
||||
{
|
||||
/** 加载完成的钩子列表 */
|
||||
protected readonly loadedList: Set<IHookObject<H, C>> = new Set();
|
||||
|
||||
/** 钩子列表 */
|
||||
private readonly hookList: Set<IHookObject<H, C>> = new Set();
|
||||
/** 钩子对象到钩子存储对象的映射 */
|
||||
private readonly hookMap: Map<Partial<H>, IHookObject<H, C>> = new Map();
|
||||
/** 钩子控制器到钩子存储对象的映射 */
|
||||
private readonly controllerMap: Map<C, IHookObject<H, C>> = new Map();
|
||||
|
||||
/**
|
||||
* 创建钩子对象的控制器
|
||||
* @param hook 钩子对象
|
||||
*/
|
||||
protected abstract createController(hook: Partial<H>): C;
|
||||
|
||||
addHook(hook: Partial<H>): C {
|
||||
const controller = this.createController(hook);
|
||||
const obj: IHookObject<H, C> = { hook, controller };
|
||||
this.hookMap.set(hook, obj);
|
||||
this.controllerMap.set(controller, obj);
|
||||
this.hookList.add(obj);
|
||||
return controller;
|
||||
}
|
||||
|
||||
loadHook(hook: Partial<H>): void {
|
||||
const obj = this.hookMap.get(hook);
|
||||
if (!obj) {
|
||||
logger.warn(85);
|
||||
return;
|
||||
}
|
||||
hook.awake?.(obj.controller);
|
||||
this.loadedList.add(obj);
|
||||
}
|
||||
|
||||
removeHook(hook: Partial<H>): void {
|
||||
const obj = this.hookMap.get(hook);
|
||||
if (!obj) return;
|
||||
obj.hook.destroy?.(obj.controller);
|
||||
this.hookList.delete(obj);
|
||||
this.loadedList.delete(obj);
|
||||
this.hookMap.delete(hook);
|
||||
this.controllerMap.delete(obj.controller);
|
||||
}
|
||||
|
||||
removeHookByController(hook: C): void {
|
||||
const obj = this.controllerMap.get(hook);
|
||||
if (!obj) return;
|
||||
obj.hook.destroy?.(obj.controller);
|
||||
this.hookList.delete(obj);
|
||||
this.loadedList.delete(obj);
|
||||
this.controllerMap.delete(hook);
|
||||
this.hookMap.delete(obj.hook);
|
||||
}
|
||||
|
||||
forEachHook(fn: (hook: Partial<H>, controller: C) => void): void {
|
||||
this.loadedList.forEach(v => fn(v.hook, v.controller));
|
||||
}
|
||||
}
|
||||
|
||||
export class HookController<H extends IHookBase> implements IHookController<H> {
|
||||
constructor(
|
||||
readonly hookable: IHookable<H, IHookController<H>>,
|
||||
readonly hook: Partial<H>
|
||||
) {}
|
||||
|
||||
load(): void {
|
||||
this.hookable.loadHook(this.hook);
|
||||
}
|
||||
|
||||
unload(): void {
|
||||
this.hookable.removeHookByController(this);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './dirtyTracker';
|
||||
export * from './hook';
|
||||
export * from './logger';
|
||||
export * from './utils';
|
||||
export * from './types';
|
||||
@@ -41,7 +41,7 @@
|
||||
"39": "Offset pool size exceeds WebGL2 limitation, ensure size type of your big image is less than $1.",
|
||||
"40": "Material used by map block $1 is not found in built asset. Please ensure you have pack it into asset.",
|
||||
"41": "You are trying to use a texture on moving block whose offset is not in the offset pool, please build it into asset after loading.",
|
||||
"42": "The layerList property of map-render element is required.",
|
||||
"42": "The layerState property of map-render element is required.",
|
||||
"1101": "Shadow extension needs 'floor-hero' extension as dependency.",
|
||||
"1201": "Floor-damage extension needs 'floor-binder' extension as dependency.",
|
||||
"1301": "Portal extension need 'floor-binder' extension as dependency.",
|
||||
@@ -132,6 +132,7 @@
|
||||
"82": "Big image offset size is larger than 64. Considier reduce big image offset bucket.",
|
||||
"83": "It seems that you call '$1' too frequently. This will extremely affect game's performance, so considering integrate them into one 'updateArea' or 'updateBlockList' call.",
|
||||
"84": "Cannot set alias '$1' for layer, since '$1' is already an alias for another layer.",
|
||||
"85": "Hook to load does not belong to current hookable object.",
|
||||
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
|
||||
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//#region 脏标记
|
||||
|
||||
export interface IDirtyMarker<T> {
|
||||
/**
|
||||
* 标记为脏,即进行了一次更新
|
||||
@@ -32,3 +34,83 @@ export interface IDirtyTracker<T> {
|
||||
*/
|
||||
hasMark(symbol: IDirtyMark): boolean;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 钩子
|
||||
|
||||
export interface IHookObject<
|
||||
H extends IHookBase,
|
||||
C extends IHookController<H>
|
||||
> {
|
||||
/** 钩子对象 */
|
||||
readonly hook: Partial<H>;
|
||||
/** 钩子控制器 */
|
||||
readonly controller: C;
|
||||
}
|
||||
|
||||
export interface IHookController<H extends IHookBase = IHookBase> {
|
||||
/** 控制器的钩子对象 */
|
||||
readonly hook: Partial<H>;
|
||||
|
||||
/**
|
||||
* 加载此控制器对应的钩子对象
|
||||
*/
|
||||
load(): void;
|
||||
|
||||
/**
|
||||
* 卸载此控制器对应的钩子对象,之后此钩子将不会再被触发
|
||||
*/
|
||||
unload(): void;
|
||||
}
|
||||
|
||||
export interface IHookBase {
|
||||
/**
|
||||
* 加载此钩子对象
|
||||
* @param controller 钩子控制器对象
|
||||
*/
|
||||
awake(controller: IHookController<this>): void;
|
||||
|
||||
/**
|
||||
* 摧毁此钩子对象
|
||||
* @param controller 钩子控制器对象
|
||||
*/
|
||||
destroy(controller: IHookController<this>): void;
|
||||
}
|
||||
|
||||
export interface IHookable<
|
||||
H extends IHookBase = IHookBase,
|
||||
C extends IHookController<H> = IHookController<H>
|
||||
> {
|
||||
/**
|
||||
* 添加钩子对象,返回控制该钩子对象的控制器
|
||||
* @param hook 钩子对象
|
||||
*/
|
||||
addHook(hook: Partial<H>): C;
|
||||
|
||||
/**
|
||||
* 加载指定的钩子对象
|
||||
* @param hook 钩子对象
|
||||
*/
|
||||
loadHook(hook: Partial<H>): void;
|
||||
|
||||
/**
|
||||
* 移除钩子对象,会调用钩子对象的 `destroy` 方法
|
||||
* @param hook 钩子对象
|
||||
*/
|
||||
removeHook(hook: Partial<H>): void;
|
||||
|
||||
/**
|
||||
* 传入钩子控制器,移除对应的钩子对象
|
||||
* @param hook 钩子控制器
|
||||
*/
|
||||
removeHookByController(hook: C): void;
|
||||
|
||||
/**
|
||||
* 遍历每个钩子
|
||||
* @param fn 对每个钩子执行的函数
|
||||
*/
|
||||
forEachHook(fn: (hook: Partial<H>, controller: C) => void): void;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Reference in new issue
Block a user