Preserve emit loop delay schedule across range cleanup
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Maintainer-controlled web client version.
|
||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||
window.CHGRID_WEB_VERSION = "2026.02.28 R306";
|
||||
window.CHGRID_WEB_VERSION = "2026.02.28 R307";
|
||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||
|
||||
@@ -87,9 +87,10 @@ export class ItemEmitRuntime {
|
||||
private readonly getSpatialConfig: (item: WorldItem) => EmitSpatialConfig,
|
||||
) {}
|
||||
|
||||
cleanup(itemId: string): void {
|
||||
cleanup(itemId: string, options?: { preserveSchedule?: boolean }): void {
|
||||
const preserveSchedule = options?.preserveSchedule === true;
|
||||
const output = this.outputs.get(itemId);
|
||||
if (!output) return;
|
||||
if (output) {
|
||||
output.element.pause();
|
||||
output.element.removeEventListener('ended', output.onEnded);
|
||||
output.element.src = '';
|
||||
@@ -99,8 +100,11 @@ export class ItemEmitRuntime {
|
||||
output.gain.disconnect();
|
||||
output.panner?.disconnect();
|
||||
this.outputs.delete(itemId);
|
||||
}
|
||||
this.pendingEmitStarts.delete(itemId);
|
||||
if (!preserveSchedule) {
|
||||
this.nextEmitStartAtMs.delete(itemId);
|
||||
}
|
||||
this.emitStartFailureCount.delete(itemId);
|
||||
}
|
||||
|
||||
@@ -139,16 +143,22 @@ export class ItemEmitRuntime {
|
||||
}
|
||||
const listeners = this.listenerPositions;
|
||||
const validIds = new Set<string>();
|
||||
const seenItemIds = new Set<string>();
|
||||
let audioCtx = this.audio.context;
|
||||
|
||||
for (const item of items) {
|
||||
seenItemIds.add(item.id);
|
||||
const emitSound = String(item.params.emitSound ?? item.emitSound ?? '').trim();
|
||||
const enabled = item.params.enabled !== false;
|
||||
const soundUrl = enabled ? this.resolveSoundUrl(emitSound) : '';
|
||||
if (!soundUrl || !this.shouldKeepRuntime(item, listeners, this.outputs.has(item.id))) {
|
||||
if (!soundUrl) {
|
||||
this.cleanup(item.id);
|
||||
continue;
|
||||
}
|
||||
if (!this.shouldKeepRuntime(item, listeners, this.outputs.has(item.id))) {
|
||||
this.cleanup(item.id, { preserveSchedule: true });
|
||||
continue;
|
||||
}
|
||||
validIds.add(item.id);
|
||||
const existing = this.outputs.get(item.id);
|
||||
if (existing && existing.soundUrl === soundUrl) {
|
||||
@@ -214,6 +224,12 @@ export class ItemEmitRuntime {
|
||||
this.cleanup(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
for (const itemId of Array.from(this.nextEmitStartAtMs.keys())) {
|
||||
if (!seenItemIds.has(itemId)) {
|
||||
this.nextEmitStartAtMs.delete(itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSpatialAudio(items: Map<string, WorldItem>, playerPosition: { x: number; y: number }): void {
|
||||
|
||||
Reference in New Issue
Block a user