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