refactor: 触发器类型问题

This commit is contained in:
AncTe committed 2026-05-17 23:27:29 +08:00
1 parent 03dc5ea60b
commit 13e8547a37
7 files changed
+146 -106

No files matched your search

@@ -1,10 +1,13 @@
import { ITrigger, ITriggerCollection, ITriggerHandler } from './types';
export class TriggerCollection implements ITriggerCollection {
export class TriggerCollection<
TEnemy = unknown,
THero = unknown
> implements ITriggerCollection<TEnemy, THero> {
/** 当前集合内部维护的触发器列表 */
private readonly triggerList: ITrigger[];
private readonly triggerList: ITrigger<TEnemy, THero>[];
constructor(triggers: Iterable<ITrigger>) {
constructor(triggers: Iterable<ITrigger<TEnemy, THero>>) {
this.triggerList = [...triggers];
}
@@ -12,17 +15,19 @@ export class TriggerCollection implements ITriggerCollection {
return this.triggerList.length;
}
async trigger<TEnemy = unknown, THero = unknown>(
handler: ITriggerHandler<TEnemy, THero>
): Promise<void> {
async trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void> {
for (const trigger of this.triggerList) {
await trigger.trigger(handler);
}
}
async *triggerIter<TEnemy = unknown, THero = unknown>(
async *triggerIter(
handler: ITriggerHandler<TEnemy, THero>
): AsyncGenerator<ITrigger, void, ITriggerHandler<TEnemy, THero> | null> {
): AsyncGenerator<
ITrigger<TEnemy, THero>,
void,
ITriggerHandler<TEnemy, THero> | null
> {
let currentHandler = handler;
for (const trigger of this.triggerList) {
await trigger.trigger(currentHandler);
@@ -35,19 +40,21 @@ export class TriggerCollection implements ITriggerCollection {
}
}
iterate(): Iterable<ITrigger> {
iterate(): Iterable<ITrigger<TEnemy, THero>> {
return this.triggerList.values();
}
push(trigger: ITrigger): void {
push(trigger: ITrigger<TEnemy, THero>): void {
this.triggerList.push(trigger);
}
unshift(trigger: ITrigger): void {
unshift(trigger: ITrigger<TEnemy, THero>): void {
this.triggerList.unshift(trigger);
}
concat(...others: ITriggerCollection[]): ITriggerCollection {
concat(
...others: ITriggerCollection<TEnemy, THero>[]
): ITriggerCollection<TEnemy, THero> {
const merged = [...this.triggerList];
for (const other of others) {
merged.push(...other.iterate());
@@ -8,11 +8,18 @@ import {
import { logger } from '@motajs/common';
import { TriggerCollection } from './collection';
export class TriggerCollector implements ITriggerCollector {
export class TriggerCollector<
TEnemy = unknown,
THero = unknown
> implements ITriggerCollector<TEnemy, THero> {
/** 当前收集器使用的注册对象 */
private registry: ITriggerRegistry | null = null;
private registry: ITriggerRegistry<TEnemy, THero> | null = null;
collect(x: number, y: number, layer: IMapLayer): ITriggerCollection {
collect(
x: number,
y: number,
layer: IMapLayer
): ITriggerCollection<TEnemy, THero> {
if (!this.registry) {
logger.warn(135);
return new TriggerCollection([]);
@@ -55,8 +62,8 @@ export class TriggerCollector implements ITriggerCollector {
const duplicate = new Set<number>();
if (staticTrigger) {
// 有静态触发器
const lessTriggers: ITrigger[] = [];
const greaterTriggers: ITrigger[] = [];
const lessTriggers: ITrigger<TEnemy, THero>[] = [];
const greaterTriggers: ITrigger<TEnemy, THero>[] = [];
// 先收集所有的触发器,并记录重复情况
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
const trigger = this.registry.create(tile.triggerType);
@@ -85,7 +92,7 @@ export class TriggerCollector implements ITriggerCollector {
return new TriggerCollection(arr);
} else {
// 没有静态触发器
const triggers: ITrigger[] = [];
const triggers: ITrigger<TEnemy, THero>[] = [];
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
const trigger = this.registry.create(tile.triggerType);
if (trigger) {
@@ -106,7 +113,7 @@ export class TriggerCollector implements ITriggerCollector {
}
}
attachRegistry(registry: ITriggerRegistry | null): void {
attachRegistry(registry: ITriggerRegistry<TEnemy, THero> | null): void {
this.registry = registry;
}
}
@@ -1,49 +1,31 @@
import { logger } from '@motajs/common';
import {
ITrigger,
ITriggerRegistry,
TriggerFactory,
TriggerStringFactory
} from './types';
import { ITrigger, ITriggerRegistry, TriggerFactory } from './types';
import { IStateBase } from '@user/data-base';
export class TriggerRegistry implements ITriggerRegistry {
export class TriggerRegistry<
TEnemy = unknown,
THero = unknown
> implements ITriggerRegistry<TEnemy, THero> {
/** 数字类型到触发器工厂的映射 */
private readonly typeMap: Map<number, TriggerFactory> = new Map();
private readonly typeMap: Map<number, TriggerFactory<TEnemy, THero>> =
new Map();
/** 字符串 id 到触发器工厂的映射 */
private readonly stringMap: Map<string, TriggerStringFactory> = new Map();
constructor(public readonly state: IStateBase<TEnemy, THero>) {}
register(type: number, factory: TriggerFactory): void {
register(type: number, factory: TriggerFactory<TEnemy, THero>): void {
if (this.typeMap.has(type)) {
logger.warn(132, 'type', type.toString());
}
this.typeMap.set(type, factory);
}
get(type: number): TriggerFactory | null {
get(type: number): TriggerFactory<TEnemy, THero> | null {
return this.typeMap.get(type) ?? null;
}
create(num: number): ITrigger | null {
create(num: number): ITrigger<TEnemy, THero> | null {
const factory = this.get(num);
if (!factory) return null;
return factory(num);
}
registerString(id: string, factory: TriggerStringFactory): void {
if (this.stringMap.has(id)) {
logger.warn(132, 'id', id);
}
this.stringMap.set(id, factory);
}
getString(id: string): TriggerStringFactory | null {
return this.stringMap.get(id) ?? null;
}
createByString(id: string): ITrigger | null {
const factory = this.getString(id);
if (!factory) return null;
return factory();
return factory(num, this.state);
}
}
+44 -45
View File
@@ -1,5 +1,10 @@
import { ITileLocator } from '@motajs/common';
import { ILayerState, IMapLayer, IStateBase } from '@user/data-base';
import {
ILayerState,
IMapLayer,
IStateBase,
IStateBaseExtended
} from '@user/data-base';
export interface ITriggerHandler<TEnemy = unknown, THero = unknown> {
/** 当前全局状态对象 */
@@ -12,11 +17,15 @@ export interface ITriggerHandler<TEnemy = unknown, THero = unknown> {
readonly locator?: ITileLocator;
}
export type TriggerFactory = (type: number) => ITrigger;
export type TriggerFactory<TEnemy, THero> = (
type: number,
state: IStateBase<TEnemy, THero>
) => ITrigger<TEnemy, THero>;
export type TriggerStringFactory = () => ITrigger;
export interface ITrigger {
export interface ITrigger<
TEnemy = unknown,
THero = unknown
> extends IStateBaseExtended<TEnemy, THero> {
/** 触发器类型标识 */
readonly type: number;
/** 触发器优先级 */
@@ -26,57 +35,39 @@ export interface ITrigger {
* 使用给定上下文触发当前触发器
* @param handler 触发上下文对象
*/
trigger<TEnemy = unknown, THero = unknown>(
handler: ITriggerHandler<TEnemy, THero>
): Promise<void>;
trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void>;
/**
* 将当前触发器包装为单元素触发器集合
*/
collection(): ITriggerCollection;
collection(): ITriggerCollection<TEnemy, THero>;
}
export interface ITriggerRegistry {
export interface ITriggerRegistry<
TEnemy = unknown,
THero = unknown
> extends IStateBaseExtended<TEnemy, THero> {
/**
* 注册一个按类型创建的触发器工厂
* @param type 触发器类型
* @param factory 触发器工厂函数
*/
register(type: number, factory: TriggerFactory): void;
register(type: number, factory: TriggerFactory<TEnemy, THero>): void;
/**
* 获取指定类型的触发器工厂
* @param type 触发器类型
*/
get(type: number): TriggerFactory | null;
get(type: number): TriggerFactory<TEnemy, THero> | null;
/**
* 根据触发器类型创建一个触发器实例,如果对应工厂不存在则返回 `null`
* @param num 触发器类型
*/
create(num: number): ITrigger | null;
/**
* 注册一个按字符串 id 查询的触发器工厂
* @param id 触发器字符串 id
* @param factory 触发器工厂函数
*/
registerString(id: string, factory: TriggerStringFactory): void;
/**
* 获取指定字符串 id 对应的触发器工厂
* @param id 触发器字符串 id
*/
getString(id: string): TriggerStringFactory | null;
/**
* 根据字符串 id 创建一个触发器实例,如果对应工厂不存在则返回 `null`
* @param id 触发器字符串 id
*/
createByString(id: string): ITrigger | null;
create(num: number): ITrigger<TEnemy, THero> | null;
}
export interface ITriggerCollection {
export interface ITriggerCollection<TEnemy, THero> {
/**
* 当前集合中的触发器数量
*/
@@ -86,54 +77,62 @@ export interface ITriggerCollection {
* 顺序触发当前集合中的所有触发器
* @param handler 初始触发上下文对象
*/
trigger<TEnemy = unknown, THero = unknown>(
handler: ITriggerHandler<TEnemy, THero>
): Promise<void>;
trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void>;
/**
* 逐个触发当前集合中的触发器,并允许为下一次推进提供新上下文
* @param handler 初始触发上下文对象
*/
triggerIter<TEnemy = unknown, THero = unknown>(
triggerIter(
handler: ITriggerHandler<TEnemy, THero>
): AsyncGenerator<ITrigger, void, ITriggerHandler<TEnemy, THero> | null>;
): AsyncGenerator<
ITrigger<TEnemy, THero>,
void,
ITriggerHandler<TEnemy, THero> | null
>;
/**
* 迭代当前集合中的所有触发器
*/
iterate(): Iterable<ITrigger>;
iterate(): Iterable<ITrigger<TEnemy, THero>>;
/**
* 向集合末尾追加一个触发器
* @param trigger 要追加的触发器
*/
push(trigger: ITrigger): void;
push(trigger: ITrigger<TEnemy, THero>): void;
/**
* 向集合头部插入一个触发器
* @param trigger 要插入的触发器
*/
unshift(trigger: ITrigger): void;
unshift(trigger: ITrigger<TEnemy, THero>): void;
/**
* 将当前集合与其他集合顺序拼接为一个新集合
* @param others 要拼接的其他集合
*/
concat(...others: ITriggerCollection[]): ITriggerCollection;
concat(
...others: ITriggerCollection<TEnemy, THero>[]
): ITriggerCollection<TEnemy, THero>;
}
export interface ITriggerCollector {
export interface ITriggerCollector<TEnemy, THero> {
/**
* 收集指定图层中某一点的所有触发器
* @param x 横坐标
* @param y 纵坐标
* @param layer 目标图层
*/
collect(x: number, y: number, layer: IMapLayer): ITriggerCollection;
collect(
x: number,
y: number,
layer: IMapLayer
): ITriggerCollection<TEnemy, THero>;
/**
* 绑定或清除当前 collector 使用的注册表
* @param registry 触发器注册表
*/
attachRegistry(registry: ITriggerRegistry | null): void;
attachRegistry(registry: ITriggerRegistry<TEnemy, THero> | null): void;
}
+2 -2
View File
@@ -6,9 +6,9 @@ export interface IStateSystem<TEnemy, THero> extends IStateBase<TEnemy, THero> {
/** 怪物上下文 */
readonly enemyContext: IEnemyContext<TEnemy, THero>;
/** 触发器注册 */
readonly triggerRegistry: ITriggerRegistry;
readonly triggerRegistry: ITriggerRegistry<TEnemy, THero>;
/** 触发器收集器 */
readonly triggerCollector: ITriggerCollector;
readonly triggerCollector: ITriggerCollector<TEnemy, THero>;
}
export interface IStateSystemExtended<TEnemy = unknown, THero = unknown> {