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:
unanmed 2026-09-11 11:08:49 +08:00
parent 1077d5f65d
commit 9c39895620
4 changed files with 86 additions and 190 deletions

View File

@ -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
)
];
}

View File

@ -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)
];
}

View File

@ -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';

View File

@ -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)
];
}