Files
Genarrative/src/games/bark-battle/application/BarkBattleController.ts

72 lines
2.1 KiB
TypeScript

import { type BarkBattleSession,createBarkBattleSession } from '../domain/BarkBattleSession';
import type { MicrophoneFailureReason } from '../domain/BarkBattleTypes';
import { BarkDetector } from '../domain/BarkDetector';
import type { BarkBattleConfig } from './BarkBattleConfig';
export class BarkBattleController {
private session: BarkBattleSession;
private detector: BarkDetector;
private sampleClockMs = 0;
constructor(private config: BarkBattleConfig) {
this.session = createBarkBattleSession(config);
this.detector = this.createDetector();
}
getSnapshot() {
return this.session.snapshot;
}
updateConfig(config: BarkBattleConfig) {
this.config = config;
this.restart();
}
finishNow() {
if (this.session.snapshot.phase !== 'playing') {
this.session = this.session.startMockRound();
}
if (this.session.snapshot.phase === 'countdown') {
this.session = this.session.tick(this.session.snapshot.countdownMs);
}
this.session = this.session.tick(this.session.snapshot.remainingMs + 1);
}
startWithMockInput() {
this.session = createBarkBattleSession(this.config).startMockRound();
this.detector = this.createDetector();
this.sampleClockMs = 0;
}
submitMockSample(volume: number) {
const events = this.detector.acceptSample({ atMs: this.sampleClockMs, volume });
for (const event of events) {
this.session = this.session.applyPlayerBark(event);
}
}
tick(deltaMs: number) {
this.sampleClockMs += deltaMs;
this.session = this.session.tick(deltaMs);
}
restart() {
this.session = createBarkBattleSession(this.config);
this.detector = this.createDetector();
this.sampleClockMs = 0;
}
failMicrophone(reason: MicrophoneFailureReason) {
this.session = this.session.failMicrophone(reason);
}
private createDetector() {
return new BarkDetector({
threshold: this.config.barkThreshold,
minBarkGapMs: this.config.minBarkGapMs,
minBarkDurationMs: this.config.minBarkDurationMs,
maxBarkDurationMs: this.config.maxBarkDurationMs,
});
}
}