feat(framework): decouple spawner update logic
Extract the core update logic from `spawnEffect` into `createSpawnUpdate`. This allows manual updates of spawned objects without relying on Preact effects, which is useful for non-reactive or imperative update cycles. Refactor `Buff` and `BuffSpawner` in `sts-like-viewer` to use the new `createSpawnUpdate` API for more efficient buff rendering.
This commit is contained in:
@@ -8,8 +8,8 @@ export type { DragDropEvent, DragDropCallback } from "./utils";
|
||||
export { hoverEffect } from "./utils";
|
||||
|
||||
// Data-driven object spawning
|
||||
export { spawnEffect } from "./spawner";
|
||||
export type { Spawner } from "./spawner";
|
||||
export { spawnEffect, createSpawnUpdate } from "./spawner";
|
||||
export type { Spawner, SpawnerCallback } from "./spawner";
|
||||
|
||||
// Scene base classes
|
||||
export {
|
||||
|
||||
@@ -4,9 +4,7 @@ import type Phaser from "phaser";
|
||||
|
||||
type GO = Phaser.GameObjects.GameObject;
|
||||
|
||||
export interface Spawner<TData, TObject extends GO = GO> {
|
||||
/** 数据源迭代器 */
|
||||
getData(): Iterable<TData>;
|
||||
export interface SpawnerCallback<TData, TObject extends GO = GO> {
|
||||
/** 获取数据的唯一键 */
|
||||
getKey(t: TData): string;
|
||||
/** 创建新对象 */
|
||||
@@ -17,15 +15,33 @@ export interface Spawner<TData, TObject extends GO = GO> {
|
||||
onUpdate(t: TData, obj: TObject): void;
|
||||
}
|
||||
|
||||
export interface Spawner<
|
||||
TData,
|
||||
TObject extends GO = GO,
|
||||
> extends SpawnerCallback<TData, TObject> {
|
||||
/** 数据源迭代器 */
|
||||
getData(): Iterable<TData>;
|
||||
}
|
||||
|
||||
export function spawnEffect<TData, TObject extends GO = GO>(
|
||||
spawner: Spawner<TData, TObject>,
|
||||
): () => void {
|
||||
const entries = new Map<string, { object: TObject; data: TData }>();
|
||||
) {
|
||||
const update = createSpawnUpdate(spawner);
|
||||
|
||||
return effect(() => {
|
||||
update(spawner.getData());
|
||||
});
|
||||
}
|
||||
|
||||
export function createSpawnUpdate<TData, TObject extends GO = GO>(
|
||||
spawner: SpawnerCallback<TData, TObject>,
|
||||
) {
|
||||
const entries = new Map<string, { object: TObject; data: TData }>();
|
||||
|
||||
function update(data: Iterable<TData>) {
|
||||
const current = new Set<string>();
|
||||
|
||||
for (const t of spawner.getData()) {
|
||||
for (const t of data) {
|
||||
const key = spawner.getKey(t);
|
||||
current.add(key);
|
||||
|
||||
@@ -48,5 +64,7 @@ export function spawnEffect<TData, TObject extends GO = GO>(
|
||||
entries.delete(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user