/**
* Реестр объектов, тикаемых движком от фиксированного шага: эффекты,
* аниматоры, вспышки. Инстанс живёт в Engine (`engine.fx`) и тикается
* между tween-ами и сценами; допускается и локальный инстанс в сцене.
*
* Владение отсутствует: запись с `destroyed === true` (Pixi-объекты
* выставляют его при destroy) вычищается сама при очередном update.
*/
/** Всё, что движок может тикать; destroyed — признак самозачистки. */
export interface Updatable {
update(dt: number): void;
destroyed?: boolean;
}
export class Updatables {
private list: Updatable[] = [];
/** Добавить и вернуть тот же объект — удобно: `engine.fx.add(emitter)`. */
add(u: Updatable): Updatable {
if (!this.list.includes(u)) this.list.push(u);
return u;
}
remove(u: Updatable): void {
const i = this.list.indexOf(u);
if (i !== -1) this.list.splice(i, 1);
}
clear(): void {
this.list.length = 0;
}
/** Обойти живые записи (например, чтобы погасить все эффекты слоя). */
forEach(fn: (u: Updatable) => void): void {
for (const u of this.list) fn(u);
}
/**
* Тик в порядке добавления; разрушенные записи не тикаются (Pixi после
* destroy обнуляет transform — касаться их нельзя) и вычищаются
* компактом на месте (без filter — тик не должен аллоцировать).
*/
update(dt: number): void {
let w = 0;
for (const u of this.list) {
if (u.destroyed) continue;
u.update(dt);
if (!u.destroyed) this.list[w++] = u; // update мог разрушить сам объект
}
this.list.length = w;
}
get count(): number {
return this.list.length;
}
}