feat: WatchDevices — MIDI device hot-plug detection#2
Merged
Conversation
- Add DeviceEventType, DeviceEvent to sdk/contracts/midi.go - Add WatchDevices(ctx) to ClientMIDI interface and MockMIDIClient - macOS: register CoreMIDI MIDINotifyProc via cgo.Handle; coremidi.Client now exposes NotifyCh <-chan int32 with native notifications - Linux: 2-second polling goroutine using ListDevices diff - Windows: 2-second polling goroutine using ListDevices diff - All dummy/stub implementations return a channel closed on ctx.Done() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sdk/contracts: - MockMIDIClient: expand struct doc, document WatchDevicesFunc / WatchDevicesCalls fields and WatchDevices method internal/coremidi: - NewClient: document CGo handle lifecycle and NotifyCh internal/midi/mididarwin (darwin + dummy): - ClientMid: struct-level doc - NewMIDIClient, ListDevices, SelectDevice, handleMIDIMessage, closeOutCh, Stop, StartCapture: doc comments - dummyMIDIClient: struct doc; WatchDevices stub doc internal/midi/midilinux (cgo + nocgo + dummy): - NewMIDIClient, ListDevices, SelectDevice, closeOutCh, StartCapture: docs - midiParser / feed: doc comments - stubClient, dummyMIDIClient: struct docs; WatchDevices stub docs internal/midi/midiwindows (windows + dummy): - HMIDIIN, midiInCaps, ClientMid: type/struct docs - NewMIDIClient, ListDevices, SelectDevice, closeOutCh, StartCapture, midiInCallback, Stop: doc comments - dummyMIDIClient: struct doc; WatchDevices stub doc Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sdk/contracts/mock_test.go: - WatchDevices uses WatchDevicesFunc when set - WatchDevices returns configured error - WatchDevices default closes channel on context cancel - WatchDevices increments WatchDevicesCalls mididarwin/client_dummy_test.go: - WatchDevices closes channel on context cancel - WatchDevices emits no events (stub) midilinux/client_dummy_test.go: - WatchDevices closes channel on context cancel - WatchDevices emits no events (stub) midilinux/client_linux_cgo_test.go (new): - WatchDevices returns non-nil channel - WatchDevices closes channel on context cancel - diffDevices: adds new device event (via export_test.go shim) - diffDevices: removes gone device event - diffDevices: no events when list unchanged midilinux/export_test.go (new): - DiffDevicesExported shim for white-box testing midiwindows/client_dummy_test.go: - WatchDevices closes channel on context cancel - WatchDevices emits no events (stub) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Windows (client_windows.go):
- stopCapture() function body was missing its declaration line, causing
'syntax error: non-declaration statement outside function body' at line 308.
Add 'func (m *ClientMid) stopCapture() error {' before the body.
macOS (coremidi/client.go):
- cgo.Handle has no Pointer() method; replace h.Pointer() with
unsafe.Pointer(uintptr(h)), which is the correct way to pass a
cgo.Handle to a C function expecting void*.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
WatchDevices(ctx context.Context) (<-chan DeviceEvent, error)to theClientMIDIinterface, enabling consumers to react in real time when a MIDI device is connected or disconnected.New API
Per-platform implementation
MIDINotifyProccallback via CGo (cgo.Handlepattern)ListDevices()every 2 smidiInGetNumDevsevery 2 sChanges
sdk/contracts/midi.go—DeviceEventType,DeviceEvent,WatchDevicesadded toClientMIDIsdk/contracts/mock.go—WatchDevicesFunc/WatchDevicesCallsadded toMockMIDIClientinternal/coremidi/client.go— CGo exportgoMidiNotify, static C bridgenotifyBridgeFn,cgo.Handlelifecycle,Client.NotifyCh,Dispose()internal/midi/mididarwin/client_darwin.go—WatchDevicesusing CoreMIDI notify channel +diffDeviceshelper;Stop()callsDispose()internal/midi/midilinux/client_linux_cgo.go—WatchDeviceswith 2 s polling +diffDevicesinternal/midi/midiwindows/client_windows.go—WatchDeviceswith 2 s polling +diffDevicesTests
mididarwinandmidiwindowsdummy clients: 100% coveragesdk/contractsmock: WatchDevices func, error, cancel, call countermidilinuxCGo client: channel returned, cancel,diffDevicesadd/remove/unchanged (viaexport_test.goshim)Notes
cgo.Handle.Delete()is called inClientMid.Stop()(darwin) viaclient.Dispose()— no handle leakName + Manufacturer; adequate for single-device use casego mod tidydoes not accept-tags; tidy was run without build tagsCo-authored-by: Copilot 223556219+Copilot@users.noreply.github.com