mirror of
https://github.com/motajs/template.git
synced 2026-09-13 18:38:50 +08:00
refactor(03-12): move event registrations into modules
- Keep the barrel limited to registration assembly and exports - Give map, hero, and control modules typed registration builders without hot-path shape validation
This commit is contained in:
parent
1077d5f65d
commit
9c39895620
@ -1,3 +1,4 @@
|
||||
import { BuiltInFunction } from 'anon-tokyo';
|
||||
import {
|
||||
IBlockEventEnv,
|
||||
IBlockEventParam,
|
||||
@ -17,11 +18,24 @@ import {
|
||||
} from '@user/data-base';
|
||||
import { getPossibleLayer } from './map';
|
||||
import {
|
||||
EventBuiltinName,
|
||||
IInsertEventEventParam,
|
||||
IInsertEventsEventParam,
|
||||
ITouchFrontEventParam
|
||||
} from './types';
|
||||
|
||||
type ControlEventBuiltinHandler<TParam> = (
|
||||
param: TParam,
|
||||
env: IBlockEventEnv
|
||||
) => void | Promise<void>;
|
||||
|
||||
function createControlEventBuiltin<TParam>(
|
||||
name: EventBuiltinName,
|
||||
handler: ControlEventBuiltinHandler<TParam>
|
||||
): BuiltInFunction {
|
||||
return { name, func: handler as BuiltInFunction['func'] };
|
||||
}
|
||||
|
||||
interface IEventSource {
|
||||
readonly priority: number;
|
||||
readonly id: string;
|
||||
@ -199,3 +213,18 @@ export async function eventInsertEvent(
|
||||
if (!param.id) return;
|
||||
await eventInsertEvents({ ids: [param.id] }, env);
|
||||
}
|
||||
|
||||
/** 创建事件控制事件的内建函数注册项 */
|
||||
export function createControlEventBuiltinRegistrations(): ReadonlyArray<BuiltInFunction> {
|
||||
return [
|
||||
createControlEventBuiltin(EventBuiltinName.TouchFront, eventTouchFront),
|
||||
createControlEventBuiltin(
|
||||
EventBuiltinName.InsertEvents,
|
||||
eventInsertEvents
|
||||
),
|
||||
createControlEventBuiltin(
|
||||
EventBuiltinName.InsertEvent,
|
||||
eventInsertEvent
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { BuiltInFunction } from 'anon-tokyo';
|
||||
import { IBlockEventEnv } from '@user/data-system';
|
||||
import { IHeroLocation, IHeroMover } from '@user/data-base';
|
||||
import {
|
||||
@ -8,7 +9,23 @@ import {
|
||||
ObjectMoveType,
|
||||
ObjectSpecialStep
|
||||
} from '@user/data-common';
|
||||
import { IMoveHeroEventParam, IMoveHeroStepEventParam } from './types';
|
||||
import {
|
||||
EventBuiltinName,
|
||||
IMoveHeroEventParam,
|
||||
IMoveHeroStepEventParam
|
||||
} from './types';
|
||||
|
||||
type HeroEventBuiltinHandler<TParam> = (
|
||||
param: TParam,
|
||||
env: IBlockEventEnv
|
||||
) => void | Promise<void>;
|
||||
|
||||
function createHeroEventBuiltin<TParam>(
|
||||
name: EventBuiltinName,
|
||||
handler: HeroEventBuiltinHandler<TParam>
|
||||
): BuiltInFunction {
|
||||
return { name, func: handler as BuiltInFunction['func'] };
|
||||
}
|
||||
|
||||
/** 启动勇士移动并等待其完整结束 */
|
||||
export function appendMoveSteps<T extends IObjectMovable>(
|
||||
@ -91,3 +108,11 @@ export async function eventMoveHeroStep(
|
||||
if (!controller) return;
|
||||
await controller.onEnd;
|
||||
}
|
||||
|
||||
/** 创建勇士控制事件的内建函数注册项 */
|
||||
export function createHeroEventBuiltinRegistrations(): ReadonlyArray<BuiltInFunction> {
|
||||
return [
|
||||
createHeroEventBuiltin(EventBuiltinName.MoveHero, eventMoveHero),
|
||||
createHeroEventBuiltin(EventBuiltinName.MoveHeroStep, eventMoveHeroStep)
|
||||
];
|
||||
}
|
||||
|
||||
@ -1,197 +1,16 @@
|
||||
import { BuiltInFunction } from 'anon-tokyo';
|
||||
import { IBlockEventEnv } from '@user/data-system';
|
||||
import { ObjectMoveStep } from '@user/data-common';
|
||||
import { eventDeleteBlock, eventMoveBlock, eventSetBlock } from './map';
|
||||
import { eventMoveHero, eventMoveHeroStep } from './hero';
|
||||
import { eventInsertEvent, eventInsertEvents, eventTouchFront } from './event';
|
||||
import {
|
||||
EventBuiltinName,
|
||||
IDeleteBlockEventParam,
|
||||
IInsertEventEventParam,
|
||||
IInsertEventsEventParam,
|
||||
IMoveBlockEventParam,
|
||||
IMoveHeroEventParam,
|
||||
ISetBlockEventParam
|
||||
} from './types';
|
||||
|
||||
function readProperty(value: object, key: string): unknown {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
||||
return descriptor ? descriptor.value : undefined;
|
||||
}
|
||||
import { createControlEventBuiltinRegistrations } from './event';
|
||||
import { createHeroEventBuiltinRegistrations } from './hero';
|
||||
import { createMapEventBuiltinRegistrations } from './map';
|
||||
|
||||
function readNumber(value: object, key: string): number | null {
|
||||
const result = readProperty(value, key);
|
||||
return typeof result === 'number' ? result : null;
|
||||
}
|
||||
|
||||
function readString(value: object, key: string): string | null {
|
||||
const result = readProperty(value, key);
|
||||
return typeof result === 'string' ? result : null;
|
||||
}
|
||||
|
||||
function readBoolean(value: object, key: string): boolean | undefined {
|
||||
const result = readProperty(value, key);
|
||||
return typeof result === 'boolean' ? result : undefined;
|
||||
}
|
||||
|
||||
function isObjectMoveStep(value: unknown): value is ObjectMoveStep {
|
||||
if (!value || typeof value !== 'object') return false;
|
||||
return typeof readProperty(value, 'type') === 'number';
|
||||
}
|
||||
|
||||
function readMoveSteps(
|
||||
value: object,
|
||||
key: string
|
||||
): readonly ObjectMoveStep[] | null {
|
||||
const result = readProperty(value, key);
|
||||
if (!Array.isArray(result)) return null;
|
||||
if (!result.every(isObjectMoveStep)) return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
function readStringArray(value: object, key: string): readonly string[] | null {
|
||||
const result = readProperty(value, key);
|
||||
if (!Array.isArray(result)) return null;
|
||||
if (!result.every(item => typeof item === 'string')) return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseSetBlock(param: object): ISetBlockEventParam | null {
|
||||
const x = readNumber(param, 'x');
|
||||
const y = readNumber(param, 'y');
|
||||
const tile = readProperty(param, 'tile');
|
||||
if (x === null || y === null) return null;
|
||||
if (typeof tile !== 'number' && typeof tile !== 'string') return null;
|
||||
return { x, y, tile };
|
||||
}
|
||||
|
||||
function parseMoveBlock(param: object): IMoveBlockEventParam | null {
|
||||
const x = readNumber(param, 'x');
|
||||
const y = readNumber(param, 'y');
|
||||
const steps = readMoveSteps(param, 'steps');
|
||||
if (x === null || y === null || !steps) return null;
|
||||
return { x, y, steps, safe: readBoolean(param, 'safe') };
|
||||
}
|
||||
|
||||
function parseDeleteBlock(param: object): IDeleteBlockEventParam | null {
|
||||
const x = readNumber(param, 'x');
|
||||
const y = readNumber(param, 'y');
|
||||
if (x === null || y === null) return null;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
function parseMoveHero(param: object): IMoveHeroEventParam | null {
|
||||
const steps = readMoveSteps(param, 'steps');
|
||||
return steps ? { steps } : null;
|
||||
}
|
||||
|
||||
function parseInsertEvents(param: object): IInsertEventsEventParam | null {
|
||||
const ids = readStringArray(param, 'ids');
|
||||
return ids ? { ids } : null;
|
||||
}
|
||||
|
||||
function parseInsertEvent(param: object): IInsertEventEventParam | null {
|
||||
const id = readString(param, 'id');
|
||||
return id === null ? null : { id };
|
||||
}
|
||||
|
||||
type BuiltinParameter = Parameters<BuiltInFunction['func']>[0];
|
||||
type BuiltinEnvironment = Parameters<BuiltInFunction['func']>[1];
|
||||
|
||||
function isBlockEventEnv(value: BuiltinEnvironment): value is IBlockEventEnv {
|
||||
return (
|
||||
'state' in value &&
|
||||
'type' in value &&
|
||||
'trigger' in value &&
|
||||
'heroLocator' in value &&
|
||||
'heroFloor' in value &&
|
||||
'triggerLocator' in value &&
|
||||
'tile' in value &&
|
||||
'layer' in value &&
|
||||
'map' in value
|
||||
);
|
||||
}
|
||||
|
||||
type EventBuiltinHandler = (
|
||||
param: BuiltinParameter,
|
||||
env: IBlockEventEnv
|
||||
) => void | Promise<void>;
|
||||
|
||||
function isBuiltinParameter(
|
||||
value: BuiltinParameter
|
||||
): value is BuiltinParameter {
|
||||
return value !== null && typeof value === 'object';
|
||||
}
|
||||
|
||||
function createBuiltin(handler: EventBuiltinHandler): BuiltInFunction['func'] {
|
||||
return (param: BuiltinParameter, env: BuiltinEnvironment) => {
|
||||
if (!isBuiltinParameter(param)) return;
|
||||
if (!isBlockEventEnv(env)) return;
|
||||
return handler(param, env);
|
||||
};
|
||||
}
|
||||
|
||||
/** 创建八个批准事件 built-in 的稳定注册项 */
|
||||
/** 组装八个批准事件 built-in 的稳定注册项 */
|
||||
export function createEventBuiltinRegistrations(): ReadonlyArray<BuiltInFunction> {
|
||||
const registrations: BuiltInFunction[] = [
|
||||
{
|
||||
name: EventBuiltinName.SetBlock,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseSetBlock(param);
|
||||
if (!parsed) return;
|
||||
return eventSetBlock(parsed, env);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.MoveBlock,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseMoveBlock(param);
|
||||
if (!parsed) return;
|
||||
return eventMoveBlock(parsed, env);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.DeleteBlock,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseDeleteBlock(param);
|
||||
if (!parsed) return;
|
||||
return eventDeleteBlock(parsed, env);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.MoveHero,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseMoveHero(param);
|
||||
if (!parsed) return;
|
||||
return eventMoveHero(parsed, env);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.MoveHeroStep,
|
||||
func: createBuiltin((_param, env) => eventMoveHeroStep({}, env))
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.TouchFront,
|
||||
func: createBuiltin((_param, env) => eventTouchFront({}, env))
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.InsertEvents,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseInsertEvents(param);
|
||||
if (!parsed) return;
|
||||
return eventInsertEvents(parsed, env);
|
||||
})
|
||||
},
|
||||
{
|
||||
name: EventBuiltinName.InsertEvent,
|
||||
func: createBuiltin((param, env) => {
|
||||
const parsed = parseInsertEvent(param);
|
||||
if (!parsed) return;
|
||||
return eventInsertEvent(parsed, env);
|
||||
})
|
||||
}
|
||||
return [
|
||||
...createMapEventBuiltinRegistrations(),
|
||||
...createHeroEventBuiltinRegistrations(),
|
||||
...createControlEventBuiltinRegistrations()
|
||||
];
|
||||
return registrations;
|
||||
}
|
||||
|
||||
export * from './event';
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { BuiltInFunction } from 'anon-tokyo';
|
||||
import { IBlockEventEnv } from '@user/data-system';
|
||||
import {
|
||||
IDeleteBlockEventParam,
|
||||
@ -8,6 +9,19 @@ import { isNil } from 'lodash-es';
|
||||
import { logger } from '@motajs/common';
|
||||
import { IGameMap, IMapLayer } from '@user/data-base';
|
||||
import { appendMoveSteps } from './hero';
|
||||
import { EventBuiltinName } from './types';
|
||||
|
||||
type MapEventBuiltinHandler<TParam> = (
|
||||
param: TParam,
|
||||
env: IBlockEventEnv
|
||||
) => void | Promise<void>;
|
||||
|
||||
function createMapEventBuiltin<TParam>(
|
||||
name: EventBuiltinName,
|
||||
handler: MapEventBuiltinHandler<TParam>
|
||||
): BuiltInFunction {
|
||||
return { name, func: handler as BuiltInFunction['func'] };
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过环境参量获取可能的地图对象
|
||||
@ -90,3 +104,12 @@ export async function eventDeleteBlock(
|
||||
layer.setBlock(0, param.x, param.y);
|
||||
}
|
||||
}
|
||||
|
||||
/** 创建地图控制事件的内建函数注册项 */
|
||||
export function createMapEventBuiltinRegistrations(): ReadonlyArray<BuiltInFunction> {
|
||||
return [
|
||||
createMapEventBuiltin(EventBuiltinName.SetBlock, eventSetBlock),
|
||||
createMapEventBuiltin(EventBuiltinName.MoveBlock, eventMoveBlock),
|
||||
createMapEventBuiltin(EventBuiltinName.DeleteBlock, eventDeleteBlock)
|
||||
];
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user