feat(manifold): add dedicated ParticleBackend (no-op transport, gates audio)
Registers a named ParticleBackend in the BackendManager + barrel in place of the inline particles PassthroughBackend. Transport is a no-op (the flow-field canvas reads engine outputs directly via rAF); selecting it gates synth audio (setMuted) like the other non-synth backends and reports a clear ready status.
This commit is contained in:
parent
711415e9ff
commit
7434b03a57
3 changed files with 38 additions and 1 deletions
|
|
@ -18,6 +18,7 @@ export { OscBridgeBackend } from './osc-backend';
|
|||
export type { OscBackendConfig } from './osc-backend';
|
||||
export { NispsOscClient } from './osc-client';
|
||||
export { PassthroughBackend } from './passthrough-backend';
|
||||
export { ParticleBackend } from './particle-backend';
|
||||
export {
|
||||
useBackendManager,
|
||||
} from './useBackendManager';
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import type { BackendId } from '../dock/output-state';
|
|||
import { WebMidiBackend } from './midi-backend';
|
||||
import { OscBridgeBackend } from './osc-backend';
|
||||
import { PassthroughBackend } from './passthrough-backend';
|
||||
import { ParticleBackend } from './particle-backend';
|
||||
|
||||
/** The slice of EngineApi the manager depends on (keeps it decoupled/testable). */
|
||||
export interface ManagerEngine {
|
||||
|
|
@ -47,7 +48,7 @@ export class BackendManager {
|
|||
['midi', backends?.midi ?? new WebMidiBackend()],
|
||||
['osc', backends?.osc ?? new OscBridgeBackend()],
|
||||
['synth', backends?.synth ?? new PassthroughBackend('synth', 'Built-in Synth — audio plays in the engine')],
|
||||
['particles', backends?.particles ?? new PassthroughBackend('particles', 'Particle visualiser')],
|
||||
['particles', backends?.particles ?? new ParticleBackend()],
|
||||
['cvgate', backends?.cvgate ?? new PassthroughBackend('cvgate', 'CV / gate (via VCV bridge)')],
|
||||
['vcv', backends?.vcv ?? new PassthroughBackend('vcv', 'VCV bridge')],
|
||||
]);
|
||||
|
|
|
|||
35
manifold/src/backends/particle-backend.ts
Normal file
35
manifold/src/backends/particle-backend.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* ParticleBackend — the output backend for the Particle System mode (the DEFAULT
|
||||
* mode).
|
||||
*
|
||||
* Transport is a NO-OP: the flow-field visualiser (console/flow-field.ts, driven
|
||||
* by ParticleStage) is a SEPARATE consumer of the engine spine — it reads
|
||||
* `engine.getOutputs()` directly in its own requestAnimationFrame loop and maps
|
||||
* the first 20 outputs onto the visual field. So there is nothing for the
|
||||
* BackendManager to "send" here.
|
||||
*
|
||||
* What this backend DOES contribute:
|
||||
* - It is a non-synth backend, so selecting it makes the BackendManager gate
|
||||
* audio (`engine.audio.setMuted(true)`) — the synth is silenced while the
|
||||
* particles are on screen, exactly like the MIDI / OSC modes.
|
||||
* - It reports a sensible "ready" status for the Outputs panel.
|
||||
*
|
||||
* It extends PassthroughBackend (the shared no-op sink) purely to keep the
|
||||
* empty-`send` / nothing-to-start behaviour in one place; the audio gate lives
|
||||
* in the manager (`setActive`), not here.
|
||||
*/
|
||||
import { PassthroughBackend } from './passthrough-backend';
|
||||
import type { BackendStatus } from './backend';
|
||||
|
||||
export class ParticleBackend extends PassthroughBackend {
|
||||
constructor() {
|
||||
super('particles', 'Particle visualiser — outputs drive the flow field (no audio)');
|
||||
}
|
||||
|
||||
override status(): BackendStatus {
|
||||
return {
|
||||
state: 'ready',
|
||||
message: 'Particle visualiser — outputs drive the flow field (no audio)',
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue