1#include <Settings/SettingsWrapper.hpp>
7#include <AH/STL/utility>
9#if defined(ESP32) || !defined(ARDUINO)
50 : sourcePipe(std::exchange(other.sourcePipe, nullptr)) {
107 : sinkPipe(std::exchange(other.sinkPipe, nullptr)) {
194 if (this->sink !=
nullptr) {
195 FATAL_ERROR(F(
"This pipe is already connected to a sink"), 0x9145);
204 if (this->source !=
nullptr) {
205 FATAL_ERROR(F(
"This pipe is already connected to a source"), 0x9146);
219 oldSink->connectSourcePipe(oldThroughIn);
226 oldSource->connectSinkPipe(oldThroughOut);
244 << F(
" because pipe is already stalled by ")
266 if (stallsrc ==
sink) {
287 << F(
" because pipe is stalled by ")
308 if (stallsrc ==
sink) {
345 FATAL_ERROR(F(
"Unable to unstall pipe (eternal stall)"), 0x4827);
346 uint8_t iterations = 10;
347 while (
isStalled() && iterations-- > 0) {
361 return "(eternal stall)";
MIDIStaller *const eternal_stall
#define BEGIN_CS_NAMESPACE
Class that routes MIDI messages from a MIDI_Source to a MIDI_Sink.
void acceptMIDIfromSource(Message msg)
Accept a MIDI message from the source, forward it to the “through” output if necessary,...
bool hasSink() const
Check if this pipe is connected to a sink.
const char * getStallerName() const
Get the name of any staller.
MIDIStaller * getStaller() const
Get any staller: returns getSinkStaller() if it's not null, getThroughStaller() otherwise.
void connectSource(MIDI_Source *source)
Set the source pointer to point to the given source.
void unstallDownstream(MIDIStaller *cause, MIDI_Source *stallsrc) override
Undoes the stalling by stallDownstream.
bool hasSource() const
Check if this pipe is connected to a source.
void stallDownstream(MIDIStaller *cause, MIDI_Source *stallsrc) override
Stall this pipe and all other pipes further downstream (following the path of the sink and the “throu...
bool hasThroughOut() const
Check if this pipe has a “through” output that sends all incoming messages from the input (source) to...
MIDIStaller * through_staller
void connectSink(MIDI_Sink *sink)
Set the sink pointer to point to the given sink.
const char * getSinkStallerName() const
Get the name of the staller (cause of the stall) that causes the sink of this pipe to be stalled.
MIDI_Pipe * getThroughOut() const
Get the pipe connected to the “through” output of this pipe.
bool isStalled() const
Check if this pipe is stalled.
MIDIStaller * sink_staller
virtual ~MIDI_Pipe()
Destructor.
const char * getThroughStallerName() const
Get the name of the staller (cause of the stall) that causes the “through” output of this pipe to be ...
void unstallUpstream(MIDIStaller *cause, MIDI_Sink *stallsrc) override
Undoes the stalling by stallUpstream.
void disconnect()
Disconnect this pipe from all other pipes, sources and sinks.
void handleStallers() const
Give the code that is stalling the MIDI pipe the opportunity to do its job and unstall the pipe.
void disconnectSink()
Set the sink pointer to null.
bool hasThroughIn() const
Check if this pipe has a “through” input that merges all messages from another pipe into the output (...
void disconnectSource()
Set the source pointer to null.
bool sinkIsUnstalledOrStalledBy(MIDIStaller *cause)
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given stalle...
void stallUpstream(MIDIStaller *cause, MIDI_Sink *stallsrc) override
Stall this pipe and all other pipes further upstream (following the path of the "trough" input).
MIDI_Pipe * getThroughIn() const
Get the pipe connected to the “through” input of this pipe.
Receives MIDI messages from a MIDI pipe.
void connectSourcePipe(MIDI_Pipe *source)
Fully connect a source pipe to this sink.
virtual void stallDownstream(MIDIStaller *, MIDI_Source *)
Base case for recursive stall function.
virtual ~MIDI_Sink()
Destructor.
friend void swap(MIDI_Sink &a, MIDI_Sink &b)
virtual void unstallDownstream(MIDIStaller *, MIDI_Source *)
Base case for recursive un-stall function.
MIDI_Sink()=default
Default constructor.
void disconnectSourcePipes()
Disconnect all source pipes that sink to this sink (recursively).
void disconnectSourcePipesShallow()
Disconnect only the first pipe connected to this sink.
bool disconnect(TrueMIDI_Source &source)
Disconnect the given source from this sink.
bool hasSourcePipe() const
Check if this sink is connected to a source pipe.
MIDI_Sink & operator=(const MIDI_Sink &)=delete
Copy assignment (copying not allowed).
Class that can send MIDI messages to a MIDI pipe.
const char * getStallerName() const
Get the name of whatever is causing this MIDI source to be stalled.
void connectSinkPipe(MIDI_Pipe *sink)
Fully connect a sink pipe to this source.
virtual ~MIDI_Source()
Destructor.
MIDIStaller * getStaller() const
Get a pointer to whatever is causing this MIDI source to be stalled.
MIDI_Source()=default
Default constructor.
void sourceMIDItoPipe(ChannelMessage)
Send a MIDI Channel Message down the pipe.
void stall(MIDIStaller *cause=eternal_stall)
Stall this MIDI source.
virtual void stallUpstream(MIDIStaller *, MIDI_Sink *)
Base case for recursive stall function.
bool isStalled() const
Check if this source can write to the sinks it connects to.
friend void swap(MIDI_Source &a, MIDI_Source &b)
void disconnectSinkPipesShallow()
Disconnect only the first pipe connected to this source.
bool disconnect(TrueMIDI_Sink &sink)
Disconnect the given sink from this source.
void disconnectSinkPipes()
Disconnect all sink pipes that this source sinks to (recursively).
MIDI_Source & operator=(const MIDI_Source &)=delete
Copy assignment (copying not allowed).
void handleStallers() const
Give the code that is stalling the MIDI sink pipes the opportunity to do its job and un-stall the pip...
virtual void unstallUpstream(MIDIStaller *, MIDI_Sink *)
Base case for recursive un-stall function.
bool hasSinkPipe() const
Check if this source is connected to a sink pipe.
void unstall(MIDIStaller *cause=eternal_stall)
Un-stall the pipes connected to this source, so other sources are allowed to send again.
#define DEBUGFN(x)
Print an expression and its function (function name and line number) to the debug output if debugging...
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
Struct that can cause a MIDI_Pipe to be stalled.
virtual const char * getName() const
Get the staller's name for debugging purposes.
virtual void handleStall()=0
Call back that should finish any MIDI messages that are in progress, and un-stall the pipe or MIDI so...
static const char * getNameNull(MIDIStaller *s)
Get the staller's name for debugging purposes.