@hiddentao/clockwork-engine
Version:
A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering
71 lines (70 loc) • 1.95 kB
JavaScript
/**
* Memory Audio Layer
*
* Headless audio implementation that tracks state without actual audio playback.
* Used for testing, replay validation, and server-side game logic.
*/
import { AudioContextState } from "../AudioLayer";
export class MemoryAudioLayer {
constructor() {
this.sounds = new Map();
this.playingSounds = new Set();
this.state = AudioContextState.RUNNING;
}
// Lifecycle
async initialize() {
this.state = AudioContextState.RUNNING;
}
destroy() {
this.state = AudioContextState.CLOSED;
this.sounds.clear();
this.playingSounds.clear();
}
// Loading
async loadSound(id, data) {
this.sounds.set(id, data);
}
// Procedural audio generation
createBuffer(channels, length, sampleRate) {
return {
numberOfChannels: channels,
length,
sampleRate,
duration: length / sampleRate,
getChannelData: (_channel) => new Float32Array(length),
};
}
loadSoundFromBuffer(id, _buffer) {
// Store a reference (in real implementation this would be the buffer)
this.sounds.set(id, `buffer:${id}`);
}
// Playback
playSound(id, _volume = 1.0, loop = false) {
// No-op for memory layer, but track playing state
if (loop) {
this.playingSounds.add(id);
}
}
stopSound(id) {
this.playingSounds.delete(id);
}
stopAll() {
this.playingSounds.clear();
}
// Context management
async tryResumeOnce() {
if (this.state === AudioContextState.SUSPENDED) {
this.state = AudioContextState.RUNNING;
}
}
getState() {
return this.state;
}
// Test helpers (not part of AudioLayer interface)
hasSound(id) {
return this.sounds.has(id);
}
isPlaying(id) {
return this.playingSounds.has(id);
}
}