feat(03-06): migrate legacy tiles to events maps

- Convert optional legacy events with safe empty defaults
- Cover TileStore consumption without trigger scalar output
This commit is contained in:
unanmed 2026-09-10 15:55:32 +08:00
parent 89e53a6500
commit a12b2d2db8
2 changed files with 66 additions and 2 deletions

View File

@ -6,7 +6,12 @@ import {
TileType
} from '@user/data-common';
export type LegacyTileData = MapDataOf<keyof NumberToId>;
interface ILegacyTileEventData {
/** 旧样板图块携带的默认事件映射 */
readonly events?: Record<number, string>;
}
export type LegacyTileData = MapDataOf<keyof NumberToId> & ILegacyTileEventData;
export class TileLegacyBridge implements ITileLegacyConverter<LegacyTileData> {
private getTileType(num: number, legacy: LegacyTileData): TileType {
@ -93,11 +98,23 @@ export class TileLegacyBridge implements ITileLegacyConverter<LegacyTileData> {
}
}
/** 将旧样板事件输入复制为新的默认事件对象 */
private getEvents(legacy: LegacyTileData): Record<number, string> {
const events: Record<number, string> = {};
for (const [priority, event] of Object.entries(legacy.events ?? {})) {
const priorityNum = Number(priority);
if (Number.isInteger(priorityNum) && typeof event === 'string') {
events[priorityNum] = event;
}
}
return events;
}
fromLegacy(num: number, legacy: LegacyTileData): ITileRawData {
return {
num,
id: legacy.id,
trigger: -1,
events: this.getEvents(legacy),
type: this.getTileType(num, legacy),
pass: this.getPass(num, legacy),
eventPass: !legacy.noPass

View File

@ -0,0 +1,47 @@
import { describe, expect, it } from 'vitest';
import { TileStore } from '@user/data-common';
import {
LegacyTileData,
TileLegacyBridge
} from '../src/legacy/tile';
describe('TileLegacyBridge events-map contract', () => {
// 验证旧样板事件对象会转换为 TileStore 可消费的默认事件映射
it('converts legacy events into the TileStore event map', () => {
const bridge = new TileLegacyBridge();
const store = new TileStore<LegacyTileData>();
store.attachLegacyConverter(bridge);
const legacy: LegacyTileData = {
id: 'yellowWall',
cls: 'terrains',
events: { 10: 'onEnter', 20: 'onTouch' },
noPass: true
};
const converted = store.fromLegacy(1, legacy);
expect(converted.events).toEqual({ 10: 'onEnter', 20: 'onTouch' });
expect(store.getEvent(1)).toEqual(
new Map([
[10, 'onEnter'],
[20, 'onTouch']
])
);
expect(converted.eventPass).toBe(false);
expect(converted).not.toHaveProperty('trigger');
});
// 验证旧样板缺少事件输入时仍生成合法的空事件映射
it('uses an empty events map when legacy input has no events', () => {
const bridge = new TileLegacyBridge();
const legacy: LegacyTileData = {
id: 'whiteWall',
cls: 'terrains'
};
const converted = bridge.fromLegacy(2, legacy);
expect(converted.events).toEqual({});
expect(converted).not.toHaveProperty('trigger');
});
});