From b0e74a5257163aef347e24a40d5a44db80c249bd Mon Sep 17 00:00:00 2001 From: hypercross Date: Sun, 19 Apr 2026 11:00:01 +0800 Subject: [PATCH] refactor(framework): simplify spawner state management Consolidate object and data tracking into a single Map in `spawnEffect` to improve clarity and reduce redundant lookups. Also switch to type-only imports for Phaser. --- packages/framework/src/spawner/index.ts | 78 ++++++++++++------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/packages/framework/src/spawner/index.ts b/packages/framework/src/spawner/index.ts index 8b01888..ef5c590 100644 --- a/packages/framework/src/spawner/index.ts +++ b/packages/framework/src/spawner/index.ts @@ -1,54 +1,52 @@ -import Phaser from 'phaser'; -import { effect } from '@preact/signals-core'; +import { effect } from "@preact/signals-core"; + +import type Phaser from "phaser"; type GO = Phaser.GameObjects.GameObject; export interface Spawner { - /** 数据源迭代器 */ - getData(): Iterable; - /** 获取数据的唯一键 */ - getKey(t: TData): string; - /** 创建新对象 */ - onSpawn(t: TData): TObject | null; - /** 销毁旧对象 */ - onDespawn(obj: TObject, t: TData): void; - /** 更新已有对象 */ - onUpdate(t: TData, obj: TObject): void; + /** 数据源迭代器 */ + getData(): Iterable; + /** 获取数据的唯一键 */ + getKey(t: TData): string; + /** 创建新对象 */ + onSpawn(t: TData): TObject | null; + /** 销毁旧对象 */ + onDespawn(obj: TObject, t: TData): void; + /** 更新已有对象 */ + onUpdate(t: TData, obj: TObject): void; } export function spawnEffect( - spawner: Spawner, + spawner: Spawner, ): () => void { - const objects = new Map(); - const spawnData = new Map(); + const entries = new Map(); - return effect(() => { - const current = new Set(); + return effect(() => { + const current = new Set(); - for (const t of spawner.getData()) { - const key = spawner.getKey(t); - current.add(key); + for (const t of spawner.getData()) { + const key = spawner.getKey(t); + current.add(key); - const existing = objects.get(key); - if (!existing) { - const obj = spawner.onSpawn(t); - if (obj) { - spawnData.set(key, t); - objects.set(key, obj); - } - } else { - if(spawnData.get(key) === t) continue; - spawner.onUpdate(t, existing); - spawnData.set(key, t); - } + const existing = entries.get(key); + if (!existing) { + const obj = spawner.onSpawn(t); + if (obj) { + entries.set(key, { object: obj, data: t }); } + } else { + if (existing.data === t) continue; + spawner.onUpdate(t, existing.object); + existing.data = t; + } + } - for (const [key, obj] of objects) { - if (!current.has(key)) { - spawner.onDespawn(obj, spawnData.get(key)!); - objects.delete(key); - spawnData.delete(key); - } - } - }); + for (const [key, entry] of entries) { + if (!current.has(key)) { + spawner.onDespawn(entry.object, entry.data); + entries.delete(key); + } + } + }); }