mirror of
https://github.com/motajs/template.git
synced 2026-11-03 07:24:30 +08:00
refactor: 触发器类型问题
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
Reference in new issue
Block a user