import * as Immutable from "immutable" ; import Store from "./internals/Store" ; import * as alloc from "./internals/allocators" ; import { watchNodeNotifications } from "./node-watcher" ; import Server from "./server" ; const StateKeys = { SERVERS : "SERVERS" , NODE_IDS : "nodeAllocator" , CONTROL_BUSSES : "controlBusAllocator" , AUDIO_BUSSES : "audioBusAllocator" , BUFFERS : "bufferAllocator" , } ; /**
 * Holds state for a Server and allocates node/bus/buffer ids,
 * stores node status and a record of compiled SynthDefs.
 *
 * Server has this has as the property: server.state
 *
 * Many of these functions are low-level accessors and allocators
 * useful for building higher-level applications that are easier
 * to use.
 *
 * Each server is stored by its unique address,
 * so multiple Servers can store state in the same
 * global Store object.
 */ export default class ServerState { readonly server : Server ; readonly store : Store ; param { Server } server param { Store } store constructor ( server , store ? ) { this . server = server ; this . store = store || new Store ( ) ; this . resetState ( ) ; watchNodeNotifications ( this . server ) ; } /**
     * Clear state and reset it to initial empty allocators.
     */ resetState ( ) { this . store . mutateState ( this . _keys ( [ ] ) , ( ) => { const options = this . server . options ; const numAudioChannels = options . numPrivateAudioBusChannels + options . numInputBusChannels + options . numOutputBusChannels ; let ab = alloc . initialBlockState ( numAudioChannels ) ; ab = alloc . reserveBlock ( ab , 0 , options . numInputBusChannels + options . numOutputBusChannels ) ; const cb = alloc . initialBlockState ( options . numControlBusChannels ) ; const bb = alloc . initialBlockState ( options . numBuffers ) ; return Immutable . Map ( { [ StateKeys . NODE_IDS ] : options . initialNodeID - 1 , [ StateKeys . AUDIO_BUSSES ] : ab , [ StateKeys . CONTROL_BUSSES ] : cb , [ StateKeys . BUFFERS ] : bb , } ) ; } ) ; } param { String } key param { Function } fn mutate ( key , fn ) { this . store . mutateState ( this . _keys ( [ key ] ) , fn ) ; } param { String } keys param { any } notSetValue getIn ( keys , notSetValue ) { return this . store . getIn ( this . _keys ( keys ) , notSetValue ) ; } /**
     * Allocates a node ID to be used for making a synth or group
     */ nextNodeID ( ) { return this . store . mutateStateAndReturn ( this . _keys ( [ StateKeys . NODE_IDS ] ) , alloc . increment ) ; } /**
     * Allocate an audio bus and return it's id.
     *
     * A bus may have many channels (stereo or more) in which case allocating reserves `numChannels` contigious busses.
     * It returns the id of the first bus.
     */ allocAudioBus ( numChannels = 1 ) { return this . _allocBlock ( StateKeys . AUDIO_BUSSES , numChannels ) ; } /**
     * Allocate a control bus and return it's id.
     *
     * A bus may have many channels (stereo or more) in which case allocating reserves `numChannels` contigious busses.
     */ allocControlBus ( numChannels = 1 ) { return this . _allocBlock ( StateKeys . CONTROL_BUSSES , numChannels ) ; } param { int } index param { int } numChannels freeAudioBus ( index , numChannels ) { this . _freeBlock ( StateKeys . AUDIO_BUSSES , index , numChannels ) ; } param { int } index param { int } numChannels freeControlBus ( index , numChannels ) { this . _freeBlock ( StateKeys . CONTROL_BUSSES , index , numChannels ) ; } param { int } numConsecutive returns { int } allocBufferID ( numConsecutive = 1 ) { return this . _allocBlock ( StateKeys . BUFFERS , numConsecutive ) ; } param { int } index param { int } numConsecutive freeBuffer ( index , numConsecutive ) { this . _freeBlock ( StateKeys . BUFFERS , index , numConsecutive ) ; } private _allocBlock ( key , numChannels ) { return this . store . mutateStateAndReturn ( this . _keys ( [ key ] ) , state => alloc . allocBlock ( state , numChannels ) ) ; } private _freeBlock ( key , index , numChannels ) { this . mutate ( key , state => alloc . freeBlock ( state , index , numChannels ) ) ; } private _keys ( keys = [ ] ) { return [ StateKeys . SERVERS , this . server . address , ... keys ] ; } }