Fix crash due to non-aligned Port allocation
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
b637cf4c4e
commit
fdc18bc10f
2 changed files with 27 additions and 20 deletions
|
|
@ -38,7 +38,7 @@ namespace engine {
|
||||||
|
|
||||||
|
|
||||||
/** This is inspired by the number of MIDI channels. */
|
/** This is inspired by the number of MIDI channels. */
|
||||||
static const int PORT_MAX_CHANNELS = 16;
|
static constexpr const int PORT_MAX_CHANNELS = 16;
|
||||||
|
|
||||||
|
|
||||||
struct Cable;
|
struct Cable;
|
||||||
|
|
@ -46,7 +46,9 @@ struct Cable;
|
||||||
|
|
||||||
struct Port {
|
struct Port {
|
||||||
/** Voltage of the port. */
|
/** Voltage of the port. */
|
||||||
union {
|
/** NOTE alignas is required in order to allow SSE usage.
|
||||||
|
Consecutive data (like in a vector) would otherwise pack Ports in a way that breaks SSE. */
|
||||||
|
union alignas(PORT_MAX_CHANNELS) {
|
||||||
/** Unstable API. Use getVoltage() and setVoltage() instead. */
|
/** Unstable API. Use getVoltage() and setVoltage() instead. */
|
||||||
float voltages[PORT_MAX_CHANNELS] = {};
|
float voltages[PORT_MAX_CHANNELS] = {};
|
||||||
/** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */
|
/** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */
|
||||||
|
|
@ -72,9 +74,6 @@ struct Port {
|
||||||
OUTPUT,
|
OUTPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** List of cables connected to this port (if output type). */
|
|
||||||
std::list<Cable*> cables;
|
|
||||||
|
|
||||||
/** Sets the voltage of the given channel. */
|
/** Sets the voltage of the given channel. */
|
||||||
void setVoltage(float voltage, int channel = 0) {
|
void setVoltage(float voltage, int channel = 0) {
|
||||||
voltages[channel] = voltage;
|
voltages[channel] = voltage;
|
||||||
|
|
@ -236,7 +235,11 @@ struct Port {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Output : Port {};
|
struct Output : Port {
|
||||||
|
/** List of cables connected to this port. */
|
||||||
|
std::list<Cable*> cables;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Input : Port {};
|
struct Input : Port {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -279,41 +279,45 @@ static void Port_setConnected(Port* that) {
|
||||||
|
|
||||||
static void Engine_updateConnected(Engine* that) {
|
static void Engine_updateConnected(Engine* that) {
|
||||||
// Find disconnected ports
|
// Find disconnected ports
|
||||||
std::set<Port*> disconnectedPorts;
|
std::set<Input*> disconnectedInputs;
|
||||||
|
std::set<Output*> disconnectedOutputs;
|
||||||
for (Module* module : that->internal->modules) {
|
for (Module* module : that->internal->modules) {
|
||||||
for (Input& input : module->inputs) {
|
for (Input& input : module->inputs) {
|
||||||
disconnectedPorts.insert(&input);
|
disconnectedInputs.insert(&input);
|
||||||
}
|
}
|
||||||
for (Output& output : module->outputs) {
|
for (Output& output : module->outputs) {
|
||||||
disconnectedPorts.insert(&output);
|
disconnectedOutputs.insert(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TerminalModule* terminalModule : that->internal->terminalModules) {
|
for (TerminalModule* terminalModule : that->internal->terminalModules) {
|
||||||
for (Input& input : terminalModule->inputs) {
|
for (Input& input : terminalModule->inputs) {
|
||||||
disconnectedPorts.insert(&input);
|
disconnectedInputs.insert(&input);
|
||||||
}
|
}
|
||||||
for (Output& output : terminalModule->outputs) {
|
for (Output& output : terminalModule->outputs) {
|
||||||
disconnectedPorts.insert(&output);
|
disconnectedOutputs.insert(&output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Cable* cable : that->internal->cables) {
|
for (Cable* cable : that->internal->cables) {
|
||||||
// Connect input
|
// Connect input
|
||||||
Input& input = cable->inputModule->inputs[cable->inputId];
|
Input& input = cable->inputModule->inputs[cable->inputId];
|
||||||
auto inputIt = disconnectedPorts.find(&input);
|
auto inputIt = disconnectedInputs.find(&input);
|
||||||
if (inputIt != disconnectedPorts.end())
|
if (inputIt != disconnectedInputs.end())
|
||||||
disconnectedPorts.erase(inputIt);
|
disconnectedInputs.erase(inputIt);
|
||||||
Port_setConnected(&input);
|
Port_setConnected(&input);
|
||||||
// Connect output
|
// Connect output
|
||||||
Output& output = cable->outputModule->outputs[cable->outputId];
|
Output& output = cable->outputModule->outputs[cable->outputId];
|
||||||
auto outputIt = disconnectedPorts.find(&output);
|
auto outputIt = disconnectedOutputs.find(&output);
|
||||||
if (outputIt != disconnectedPorts.end())
|
if (outputIt != disconnectedOutputs.end())
|
||||||
disconnectedPorts.erase(outputIt);
|
disconnectedOutputs.erase(outputIt);
|
||||||
Port_setConnected(&output);
|
Port_setConnected(&output);
|
||||||
}
|
}
|
||||||
// Disconnect ports that have no cable
|
// Disconnect ports that have no cable
|
||||||
for (Port* port : disconnectedPorts) {
|
for (Input* input : disconnectedInputs) {
|
||||||
Port_setDisconnected(port);
|
Port_setDisconnected(input);
|
||||||
DISTRHO_SAFE_ASSERT(port->cables.empty());
|
}
|
||||||
|
for (Output* output : disconnectedOutputs) {
|
||||||
|
Port_setDisconnected(output);
|
||||||
|
DISTRHO_SAFE_ASSERT(output->cables.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue