#nullable enable
using System;
using NAudio.Midi;
namespace T3.IoServices;
///
/// Parallel dispatch path for replaying recorded IO events through graph-side input
/// operators (MidiInput, OscInput) without going through the normal
/// hardware-bound MidiConnectionManager / OscConnectionManager routes.
/// Makes those ops fire identically whether their events come from a real device or
/// from a recorded .data file, identified by the same device name.
///
///
/// Does not reach CompatibleMidiDevice instances (the surface controllers
/// driving variations / snapshots) — those filter by sender == _midiInputConnection
/// and always need a real . Variation replay is out of scope for
/// this bus by design.
///
/// The producer side is the SimulateIoData operator; consumers subscribe in
/// their constructor and unsubscribe on dispose. Real-time recording
/// () only listens to the connection managers, so
/// simulated events never feed back into a concurrent recording.
///
///
public static class SimulatedIoBus
{
///
/// One replayed MIDI event. Identifies the source device by product name (the same
/// string MidiInput.Device matches against) rather than by
/// instance, so simulation works without the original hardware connected.
///
/// Source device name as recorded.
/// Reconstructed NAudio MIDI event — typically NoteEvent,
/// ControlChangeEvent, PitchWheelChangeEvent, or
/// ChannelAfterTouchEvent.
public sealed record SimulatedMidiEvent(string DeviceProductName, MidiEvent Event);
///
/// One replayed OSC event. The port matches the recorded source's port so an
/// OscInput bound to that port receives the event identically to a real one.
///
public sealed record SimulatedOscEvent(int Port, string Address, object Value);
public static event Action? MidiEventReceived;
public static event Action? OscEventReceived;
public static void DispatchMidi(SimulatedMidiEvent ev) => MidiEventReceived?.Invoke(ev);
public static void DispatchOsc(SimulatedOscEvent ev) => OscEventReceived?.Invoke(ev);
}