11package com .hypercube .mpm .app ;
22
3- import com .hypercube .mpm .config .ConfigurationFactory ;
3+ import com .hypercube .mpm .config .ConfigurationService ;
44import com .hypercube .mpm .config .ProjectConfiguration ;
55import com .hypercube .mpm .javafx .bootstrap .JavaFXApplication ;
66import com .hypercube .mpm .javafx .widgets .dialog .generic .GenericDialogController ;
5353@ Slf4j
5454public class DeviceStateManager {
5555 private final MainModel model ;
56- private final ConfigurationFactory configurationFactory ;
56+ private final ConfigurationService configurationService ;
5757 private final MidiDeviceRequester midiDeviceRequester ;
5858 private final PatchesManager patchesManager ;
5959
60- public DeviceStateManager (ConfigurationFactory configurationFactory , MidiDeviceRequester midiDeviceRequester , PatchesManager patchesManager ) {
61- this .configurationFactory = configurationFactory ;
60+ public DeviceStateManager (ConfigurationService configurationService , MidiDeviceRequester midiDeviceRequester , PatchesManager patchesManager ) {
61+ this .configurationService = configurationService ;
6262 this .midiDeviceRequester = midiDeviceRequester ;
6363 this .patchesManager = patchesManager ;
6464 this .model = MainModel .getObservableInstance ();
@@ -98,20 +98,13 @@ public void onModeChanged(String selectedMode) {
9898 * @param selectedPatch optional, can be null
9999 */
100100 public void initDeviceStateFromConfig (DeviceStateId id , Patch selectedPatch ) {
101- var cfg = configurationFactory .getProjectConfiguration ();
102- var device = cfg .getMidiDeviceLibrary ()
103- .getDevice (id .getName ())
104- .orElseThrow ();
101+ var cfg = configurationService .getProjectConfiguration ();
102+ var device = getMidiDeviceDefinition (id );
105103 DeviceState deviceState ;
106104 deviceState = new DeviceState ();
107105 deviceState .setId (new DeviceStateId (id .getName (), id .getMode (), selectedPatch == null ? id .getChannel () : selectedPatch .getChannel ()));
108- if (deviceState .getMidiOutDevice () == null && device .getOutputMidiDevice () != null ) {
109- try {
110- deviceState .setMidiOutDevice (cfg .getMidiPortsManager ()
111- .openOutput (device .getOutputMidiDevice ()));
112- } catch (MidiError e ) {
113- log .error ("Unable to open device {}" , device .getOutputMidiDevice (), e );
114- }
106+ if (deviceState .getMidiOutDevice () == null ) {
107+ updateDeviceStateOutputMidiPort (device , deviceState );
115108 }
116109 if (selectedPatch != null ) {
117110 deviceState .setCurrentPatch (selectedPatch );
@@ -186,7 +179,6 @@ public void onDeviceChanged(MidiDeviceDefinition device) {
186179 model .setDeviceModes (List .of ());
187180 model .setModeChannels (List .of ());
188181 } else {
189- dumpStates ();
190182 final DeviceStateId id = getLastUsedDeviceStateId (device );
191183 refreshDeviceModes (device );
192184 refreshCurrentDeviceState (id );
@@ -197,7 +189,7 @@ public void onDeviceChanged(MidiDeviceDefinition device) {
197189 * If the mode is changed, change effectively the mode in the hardware device via MIDI
198190 */
199191 public void changeModeOnDevice (MidiDeviceDefinition device , DeviceState currentState , String newModeName , boolean force ) {
200- var cfg = configurationFactory .getProjectConfiguration ();
192+ var cfg = configurationService .getProjectConfiguration ();
201193 if (!currentState .getId ()
202194 .getMode ()
203195 .equals (newModeName ) || force ) {
@@ -280,8 +272,15 @@ public void refreshModeProperties(MidiDeviceDefinition device, DeviceState state
280272 }
281273
282274 public void reloadMidiDeviceLibrary () {
283- configurationFactory .forceLoadMidiDeviceLibrary ();
275+ configurationService .forceLoadMidiDeviceLibrary ();
284276 initModel ();
277+ // Update the output midi ports in case they have changed
278+ model .getDeviceStates ()
279+ .forEach ((deviceStateId , state ) -> {
280+ if (state .getMidiOutDevice () != null ) {
281+ updateDeviceStateOutputMidiPort (getMidiDeviceDefinition (deviceStateId ), state );
282+ }
283+ });
285284 }
286285
287286 @ PostConstruct
@@ -301,7 +300,7 @@ public int getCurrentOutputChannel() {
301300 * Restore the state of all devices when the application start
302301 */
303302 public void initDevices () {
304- var cfg = configurationFactory .getProjectConfiguration ();
303+ var cfg = configurationService .getProjectConfiguration ();
305304 List <String > devices = model .getDevices ();
306305 log .info ("Midi Device Library active: {}" , devices .size ());
307306 if (devices
@@ -353,6 +352,25 @@ public void initDevices() {
353352 }
354353 }
355354
355+ public void updateDeviceStateOutputMidiPort (MidiDeviceDefinition device , DeviceState deviceState ) {
356+ if (device .getOutputMidiDevice () != null ) {
357+ try {
358+ deviceState .setMidiOutDevice (configurationService .getProjectConfiguration ()
359+ .getMidiPortsManager ()
360+ .openOutput (device .getOutputMidiDevice ()));
361+ } catch (MidiError e ) {
362+ log .error ("Unable to open device {}" , device .getOutputMidiDevice (), e );
363+ }
364+ }
365+ }
366+
367+ private MidiDeviceDefinition getMidiDeviceDefinition (DeviceStateId id ) {
368+ return configurationService .getProjectConfiguration ()
369+ .getMidiDeviceLibrary ()
370+ .getDevice (id .getName ())
371+ .orElseThrow ();
372+ }
373+
356374 private void executeOnDeviceOutput (ProjectConfiguration cfg , String deviceName , Consumer <MidiOutDevice > fct ) {
357375 var device = cfg .getMidiDeviceLibrary ()
358376 .getDevice (deviceName )
@@ -384,19 +402,15 @@ private List<MidiPresetCategory> getModeCategories(MidiDeviceMode mode, int chan
384402 }
385403
386404 private MidiDeviceDefinition getSelectedDevice () {
387- return configurationFactory .getProjectConfiguration ()
388- .getMidiDeviceLibrary ()
389- .getDevice (model .getCurrentDeviceState ()
390- .getId ()
391- .getName ())
392- .orElseThrow ();
405+ return getMidiDeviceDefinition (model .getCurrentDeviceState ()
406+ .getId ());
393407 }
394408
395409 /**
396410 * When possible we replace the MIDI port name by a known device
397411 */
398412 private List <String > buildMidiInPortsList () {
399- var cfg = configurationFactory .getProjectConfiguration ();
413+ var cfg = configurationService .getProjectConfiguration ();
400414 return cfg .getMidiPortsManager ()
401415 .getInputs ()
402416 .stream ()
@@ -419,7 +433,7 @@ private List<String> buildMidiInPortsList() {
419433 * When possible we replace the MIDI port name by a known device
420434 */
421435 private List <String > buildMidiThruPortsList () {
422- var cfg = configurationFactory .getProjectConfiguration ();
436+ var cfg = configurationService .getProjectConfiguration ();
423437 return cfg .getMidiPortsManager ()
424438 .getOutputs ()
425439 .stream ()
@@ -439,7 +453,7 @@ private List<String> buildMidiThruPortsList() {
439453 }
440454
441455 private List <String > buildDeviceList () {
442- var cfg = configurationFactory .getProjectConfiguration ();
456+ var cfg = configurationService .getProjectConfiguration ();
443457 return cfg .getMidiDeviceLibrary ()
444458 .getDevices ()
445459 .values ()
@@ -510,17 +524,17 @@ private DeviceStateId getOrCreateDeviceStateId(MidiDeviceDefinition device, Stri
510524 * @param id key of the state in the map
511525 */
512526 private void refreshCurrentDeviceState (DeviceStateId id ) {
527+ log .info ("refreshCurrentDeviceState {}" , Optional .ofNullable (id )
528+ .map (DeviceStateId ::toString )
529+ .orElse ("null" ));
513530 if (id == null ) {
514531 // device without modes, so no id, we empty everything
515532 model .setModeCategories (List .of ());
516533 model .setModeBanks (List .of ());
517534 model .setModeChannels (List .of ());
518535 model .setCurrentDeviceState (null );
519536 } else {
520- var device = configurationFactory .getProjectConfiguration ()
521- .getMidiDeviceLibrary ()
522- .getDevice (id .getName ())
523- .orElseThrow ();
537+ var device = getMidiDeviceDefinition (id );
524538
525539 DeviceState deviceState = model .getDeviceStates ()
526540 .get (id );
@@ -622,6 +636,7 @@ private DeviceStateId getLastUsedDeviceStateId(MidiDeviceDefinition device) {
622636 * Note: it is perfectly possible to have no modes for a device (DAW device for instance)
623637 */
624638 private void refreshDeviceModes (MidiDeviceDefinition device ) {
639+ log .info ("refreshDeviceModes for device {}" , device .getDeviceName ());
625640 var modes = device .getDeviceModes ()
626641 .keySet ()
627642 .stream ()
0 commit comments