Closed jkbelcher closed 2 years ago
Nice catch on this, I've gone ahead and fixed this another way. I do think we should check the connected state, but think we should also be catching the receiver.send() exception in these cases, and then marking the device as disconnected.
Relatedly, I realized the LXListenableParameter thing should really check this.value directly - getValue() is no good there as a CompoundParameter with active modulation will return whatever modulated value its got at that period in time, which is not what we want... rather the underlying base setting.
Here's the default fix: https://github.com/heronarts/LX/commit/da4a4c1480d42eaa905daf5ec1b0a39e032d8a4e
Here's the output device fix checking for connected state, catching exceptions and flagging a detected disconnection when that happens: https://github.com/heronarts/LX/commit/734b4bd6bcadc49a87c1987a376f0bdf7066078e
I don't actually have the device you're working with here though. Do you mind pulling these updates and test if it fixes the scenario that you're running into, and that the control surface keeps operating? I'll close this pull request but def open another one if the issue persists.
Looks good! Midi surface unplugs now without causing errors on subsequent UI actions. Also reconnects fine when plugged back in.
There are a few ways to fix this, so sending this simple version to demonstrate the problem.
After a midi device is hot-unplugged the following actions will cause a fatal crash due to disconnected midi output: -Unchecking the Enabled box in the midi list, which on APC40mkII attempts to set device controls to zero and send sysex for generic mode. -Changing channel focus, adding a pattern, etc, which fires listeners on midi surfaces which in turn attempt to send notes.
Possible solutions: -Swallow the send attempts as per this solution, which doesn't feel exactly right but fixes all existing surfaces. -Require surfaces to monitor connected state by overriding this new onDisconnect() method and not send if disconnected. Seems redundant to make each surface do the tracking of the state. -Maintain connected state flag in LXMidiSurface and make accessible to subclasses with method. Require surfaces to check state using LXMidiSurface.isConnected() or similar each time before attempting send() or sendSysex().