Better architectural distinction between live coding mode and composition mode

This commit is contained in:
2025-10-15 11:04:27 +02:00
parent 46925f5c2e
commit bbdb01200e
11 changed files with 434 additions and 160 deletions

View File

@ -0,0 +1,98 @@
import type { CsoundStore } from './store';
import type { ProjectMode } from '../project-system/types';
import { CompositionStrategy, LiveCodingStrategy, type ExecutionStrategy } from './execution-strategies';
export type EvalSource = 'selection' | 'block' | 'document';
export interface ExecutionSession {
mode: ProjectMode;
projectId: string | null;
isActive: boolean;
startTime: Date;
}
export class ExecutionContext {
private session: ExecutionSession | null = null;
private strategy: ExecutionStrategy;
private currentMode: ProjectMode;
private contentProvider: (() => string) | null = null;
constructor(
private csound: CsoundStore,
mode: ProjectMode
) {
this.currentMode = mode;
this.strategy = this.createStrategyForMode(mode);
}
get mode(): ProjectMode {
return this.currentMode;
}
get activeSession(): ExecutionSession | null {
return this.session;
}
setContentProvider(provider: () => string): void {
this.contentProvider = provider;
}
async startSession(projectId: string | null): Promise<void> {
await this.endSession();
this.session = {
mode: this.currentMode,
projectId,
isActive: true,
startTime: new Date()
};
if (this.currentMode === 'livecoding') {
this.resetStrategy();
}
}
async endSession(): Promise<void> {
if (!this.session?.isActive) return;
if (this.currentMode === 'livecoding') {
await this.csound.stop();
this.resetStrategy();
}
this.session = { ...this.session, isActive: false };
}
async execute(code: string, source: EvalSource): Promise<void> {
if (this.currentMode === 'livecoding' && (!this.session || !this.session.isActive)) {
await this.startSession(this.session?.projectId ?? null);
}
const fullContent = this.contentProvider?.() ?? '';
await this.strategy.execute(this.csound, code, fullContent, source);
}
async switchMode(newMode: ProjectMode): Promise<void> {
if (newMode === this.currentMode) return;
await this.endSession();
this.currentMode = newMode;
this.strategy = this.createStrategyForMode(newMode);
}
private createStrategyForMode(mode: ProjectMode): ExecutionStrategy {
return mode === 'livecoding'
? new LiveCodingStrategy()
: new CompositionStrategy();
}
private resetStrategy(): void {
if (this.strategy instanceof LiveCodingStrategy) {
this.strategy.reset();
}
}
async destroy(): Promise<void> {
await this.endSession();
}
}