11package  baaahs.plugin.midi 
22
3- import  baaahs.PubSub 
43import  baaahs.ShowPlayer 
54import  baaahs.gl.GlContext 
65import  baaahs.gl.data.EngineFeedContext 
@@ -14,19 +13,24 @@ import baaahs.plugin.*
1413import  baaahs.show.Feed 
1514import  baaahs.show.FeedBuilder 
1615import  baaahs.sim.BridgeClient 
16+ import  baaahs.sim.SimulatorSettingsManager 
1717import  baaahs.ui.Observable 
1818import  baaahs.ui.addObserver 
1919import  baaahs.util.Logger 
2020import  baaahs.util.RefCounted 
2121import  baaahs.util.RefCounter 
22+ import  baaahs.util.globalLaunch 
2223import  kotlinx.cli.ArgParser 
2324import  kotlinx.cli.ArgType 
2425import  kotlinx.cli.default 
2526import  kotlinx.serialization.SerialName 
27+ import  kotlinx.serialization.Serializable 
2628
2729class  MidiPlugin  internal constructor(
28-     internal  val  midiSource :   MidiSource ,
30+     internal  val  midiSystem :   MidiSystem ,
2931) : OpenServerPlugin, OpenClientPlugin {
32+     private  val  midiSource =  midiSystem.midiSources.firstOrNull() ? :  MidiSource .None 
33+ 
3034    override  val  packageName:  String  =  MidiPlugin .id
3135    override  val  title:  String  =  " Midi" 
3236
@@ -98,7 +102,6 @@ class MidiPlugin internal constructor(
98102
99103    interface  Args  {
100104        val  enableMidi:  Boolean 
101-         val  midiSource:  MidiSource ?  get() =  null 
102105    }
103106
104107    companion  object  :  Plugin <Args >, SimulatorPlugin  {
@@ -120,85 +123,83 @@ class MidiPlugin internal constructor(
120123        override  fun  getArgs (parser :  ArgParser ): Args  =  ParserArgs (parser)
121124
122125        override  fun  openForServer (pluginContext :  PluginContext , args :  Args ): OpenServerPlugin  {
123-             val  midiSource =  if  (args.enableMidi) {
124-                 args.midiSource ? :  createServerMidiSource(pluginContext)
125-             } else  MidiSource .None 
126-             return  MidiPlugin (
127-                 PubSubPublisher (midiSource, pluginContext)
128-             )
126+             val  midiSystem =  if  (args.enableMidi) {
127+                 createMidiSystem(pluginContext)
128+             } else  MidiSystem .None 
129+ 
130+             return  MidiPlugin (midiSystem)
129131        }
130132
131133        override  fun  openForClient (pluginContext :  PluginContext ): OpenClientPlugin  = 
132-             MidiPlugin (PubSubSubscriber (pluginContext.pubSub) )
134+             MidiPlugin (MidiSystem . None )
133135
134-         override  fun  openForSimulator (): OpenSimulatorPlugin  = 
136+         override  fun  openForSimulator (
137+             simulatorSettingsManager :  SimulatorSettingsManager 
138+         ): OpenSimulatorPlugin  = 
135139            object  :  OpenSimulatorPlugin  {
136-                 override  fun  getBridgePlugin (pluginContext :  PluginContext ): OpenBridgePlugin  = 
137-                     MidiBridgePlugin (createServerMidiSource(pluginContext), pluginContext)
140+                 private  val  midiHardwareSimulator =  MidiHardwareSimulator (simulatorSettingsManager)
141+ 
142+                 override  fun  getBridgePlugin (pluginContext :  PluginContext ): OpenBridgePlugin ?  =  null 
138143
139144                override  fun  getServerPlugin (pluginContext :  PluginContext , bridgeClient :  BridgeClient ) = 
140145                    openForServer(pluginContext, object  :  Args  { override  val  enableMidi:  Boolean  get() =  true  })
141146
142147                override  fun  getClientPlugin (pluginContext :  PluginContext ): OpenClientPlugin  = 
143148                    openForClient(pluginContext)
144-             }
145149
146-         private  val  midiDataTopic =  PubSub .Topic (" plugins/$id /midiData"  , MidiData .serializer())
147-     }
148- 
149-     /* * Copy midi data from [midiSource] to a bridge PubSub channel. */ 
150-     class  MidiBridgePlugin (
151-         private  val  midiSource :  MidiSource ,
152-         pluginContext :  PluginContext 
153-     ) : OpenBridgePlugin {
154-         private  val  channel =  pluginContext.pubSub.openChannel(midiDataTopic, unknownMidi) { }
155- 
156-         init  {
157-             midiSource.addObserver { channel.onChange(it.getMidiData()) }
158-         }
150+                 override  fun  getHardwareSimulators (): List <HardwareSimulator > = 
151+                     listOf (midiHardwareSimulator)
152+             }
159153    }
154+ }
160155
161-     class  PubSubPublisher (
162-         midiSource :  MidiSource ,
163-         pluginContext :  PluginContext 
164-     ) : Observable(), MidiSource {
165-         private  var  midiData:  MidiData  =  midiSource.getMidiData()
156+ class  MidiHardwareSimulator (
157+     private  val  simulatorSettingsManager :  SimulatorSettingsManager 
158+ ) : HardwareSimulator, MidiSystem, Observable() {
159+     override  val  title:  String  =  " MIDI" 
166160
167-         val  channel =  pluginContext.pubSub.openChannel(midiDataTopic, midiData) {
168-             logger.warn { " MidiData update from client? Huh?"   }
169-             midiData =  it
170-             notifyChanged()
171-         }
161+     override  var  midiSources:  List <MidiSource > =  emptyList()
162+         private  set
172163
173-         init  {
174-             midiSource.addObserver {
175-                 val  newMidiData =  it.getMidiData()
176-                 midiData =  newMidiData
177-                 notifyChanged()
178-                 channel.onChange(newMidiData)
164+     override  suspend  fun  start () {
165+         logger.info { " Starting MIDI hardware simulator."   }
166+         simulatorSettingsManager.addObserver(fireImmediately =  true ) {
167+             globalLaunch {
168+                 onSettingsChange()
179169            }
180170        }
181- 
182-         override  fun  getMidiData (): MidiData  =  midiData
183- 
184171    }
185172
186-     class  PubSubSubscriber (
187-         pubSub :  PubSub .Endpoint ,
188-         defaultMidiData :  MidiData  = unknownMidi
189-     ) : Observable(), MidiSource {
190-         private  var  midiData:  MidiData  =  defaultMidiData
173+     private  fun  onSettingsChange () {
174+         val  config =  simulatorSettingsManager.simSettings
175+             .getConfig(MidiPlugin .id, MidiHardwareSimulatorSettings .serializer())
176+             ? :  MidiHardwareSimulatorSettings (emptyList())
191177
192-         init  {
193-             pubSub.openChannel(midiDataTopic, midiData) {
194-                 midiData =  it
195-                 notifyChanged()
196-             }
197-         }
178+         println (" config = $config "  )
179+         midiSources =  config.devices.map { SimMidiSource (it.name) }
180+     }
198181
199-         override  fun  getMidiData (): MidiData  =  midiData
182+     companion  object  {
183+         private  val  logger =  Logger <MidiHardwareSimulator >()
184+     }
185+ }
200186
187+ @Serializable
188+ data class  MidiHardwareSimulatorSettings (
189+     val  devices :  List <SimMidiDevice >
190+ )
191+ 
192+ @Serializable
193+ data class  SimMidiDevice (
194+     val  name :  String 
195+ )
196+ 
197+ class  SimMidiSource (
198+     override  val  name :  String 
199+ ) : MidiSource, Observable() {
200+     override  fun  getMidiData (): MidiData  {
201+         TODO (" not implemented"  )
201202    }
202203}
203204
204- internal  expect  fun  createServerMidiSource (pluginContext :  PluginContext ): MidiSource 
205+ internal  expect  fun  createMidiSystem (pluginContext :  PluginContext ): MidiSystem 
0 commit comments