@@ -1423,6 +1423,19 @@ typedef struct { | |||
*/ | |||
const char* value; | |||
#ifdef __cplusplus | |||
/*! | |||
* Check if valid. | |||
*/ | |||
bool isValid() const noexcept | |||
{ | |||
if (type == nullptr || type[0] == '\0') return false; | |||
if (key == nullptr || key [0] == '\0') return false; | |||
if (value == nullptr) return false; | |||
return true; | |||
} | |||
#endif /* __cplusplus */ | |||
} CustomData; | |||
/*! | |||
@@ -114,10 +114,13 @@ const char* RackGraph::MIDI::getName(const bool isInput, const uint portId) cons | |||
{ | |||
for (LinkedList<PortNameToId>::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& port(it.getValue()); | |||
static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
if (port.port == portId) | |||
return port.name; | |||
const PortNameToId& portNameToId(it.getValue(portNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (portNameToId.port == portId) | |||
return portNameToId.name; | |||
} | |||
return nullptr; | |||
@@ -127,13 +130,16 @@ uint RackGraph::MIDI::getPortId(const bool isInput, const char portName[], bool* | |||
{ | |||
for (LinkedList<PortNameToId>::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& port(it.getValue()); | |||
static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
const PortNameToId& portNameToId(it.getValue(portNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (std::strcmp(port.name, portName) == 0) | |||
if (std::strncmp(portNameToId.name, portName, STR_MAX) == 0) | |||
{ | |||
if (ok != nullptr) | |||
*ok = true; | |||
return port.port; | |||
return portNameToId.port; | |||
} | |||
} | |||
@@ -315,28 +321,31 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n | |||
for (LinkedList<ConnectionToId>::Itenerator it=connections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connection(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
if (connection.id != connectionId) | |||
if (connectionToId.id != connectionId) | |||
continue; | |||
uint otherGroup, otherPort, carlaPort; | |||
if (connection.groupA == RACK_GRAPH_GROUP_CARLA) | |||
if (connectionToId.groupA == RACK_GRAPH_GROUP_CARLA) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(connection.groupB != RACK_GRAPH_GROUP_CARLA, false); | |||
CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB != RACK_GRAPH_GROUP_CARLA, false); | |||
carlaPort = connection.portA; | |||
otherGroup = connection.groupB; | |||
otherPort = connection.portB; | |||
carlaPort = connectionToId.portA; | |||
otherGroup = connectionToId.groupB; | |||
otherPort = connectionToId.portB; | |||
} | |||
else | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(connection.groupB == RACK_GRAPH_GROUP_CARLA, false); | |||
CARLA_SAFE_ASSERT_RETURN(connectionToId.groupB == RACK_GRAPH_GROUP_CARLA, false); | |||
carlaPort = connection.portB; | |||
otherGroup = connection.groupA; | |||
otherPort = connection.portA; | |||
carlaPort = connectionToId.portB; | |||
otherGroup = connectionToId.groupA; | |||
otherPort = connectionToId.portA; | |||
} | |||
CARLA_SAFE_ASSERT_RETURN(carlaPort > RACK_GRAPH_CARLA_PORT_NULL && carlaPort < RACK_GRAPH_CARLA_PORT_MAX, false); | |||
@@ -387,7 +396,7 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n | |||
return false; | |||
} | |||
engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, 0, 0, 0.0f, nullptr); | |||
engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connectionToId.id, 0, 0, 0.0f, nullptr); | |||
connections.list.remove(it); | |||
return true; | |||
@@ -424,25 +433,28 @@ const char* const* RackGraph::getConnections() const noexcept | |||
for (LinkedList<ConnectionToId>::Itenerator it=connections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connection(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
uint otherGroup, otherPort, carlaPort; | |||
if (connection.groupA == RACK_GRAPH_GROUP_CARLA) | |||
if (connectionToId.groupA == RACK_GRAPH_GROUP_CARLA) | |||
{ | |||
CARLA_SAFE_ASSERT_CONTINUE(connection.groupB != RACK_GRAPH_GROUP_CARLA); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB != RACK_GRAPH_GROUP_CARLA); | |||
carlaPort = connection.portA; | |||
otherGroup = connection.groupB; | |||
otherPort = connection.portB; | |||
carlaPort = connectionToId.portA; | |||
otherGroup = connectionToId.groupB; | |||
otherPort = connectionToId.portB; | |||
} | |||
else | |||
{ | |||
CARLA_SAFE_ASSERT_CONTINUE(connection.groupB == RACK_GRAPH_GROUP_CARLA); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.groupB == RACK_GRAPH_GROUP_CARLA); | |||
carlaPort = connection.portB; | |||
otherGroup = connection.groupA; | |||
otherPort = connection.portA; | |||
carlaPort = connectionToId.portB; | |||
otherGroup = connectionToId.groupA; | |||
otherPort = connectionToId.portA; | |||
} | |||
CARLA_SAFE_ASSERT_CONTINUE(carlaPort > RACK_GRAPH_CARLA_PORT_NULL && carlaPort < RACK_GRAPH_CARLA_PORT_MAX); | |||
@@ -679,7 +691,8 @@ void RackGraph::processHelper(CarlaEngine::ProtectedData* const data, const floa | |||
// connect input buffers | |||
for (LinkedList<uint>::Itenerator it = audio.connectedIn1.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& port(it.getValue()); | |||
const uint& port(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(port < inputs); | |||
if (noConnections) | |||
@@ -700,7 +713,8 @@ void RackGraph::processHelper(CarlaEngine::ProtectedData* const data, const floa | |||
for (LinkedList<uint>::Itenerator it = audio.connectedIn2.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& port(it.getValue()); | |||
const uint& port(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(port < inputs); | |||
if (noConnections) | |||
@@ -734,7 +748,8 @@ void RackGraph::processHelper(CarlaEngine::ProtectedData* const data, const floa | |||
{ | |||
for (LinkedList<uint>::Itenerator it = audio.connectedOut1.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& port(it.getValue()); | |||
const uint& port(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(port < outputs); | |||
FloatVectorOperations::add(outBuf[port], audio.outBuf[0], iframes); | |||
@@ -745,7 +760,8 @@ void RackGraph::processHelper(CarlaEngine::ProtectedData* const data, const floa | |||
{ | |||
for (LinkedList<uint>::Itenerator it = audio.connectedOut2.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& port(it.getValue()); | |||
const uint& port(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(port < outputs); | |||
FloatVectorOperations::add(outBuf[port], audio.outBuf[1], iframes); | |||
@@ -1317,24 +1333,27 @@ bool PatchbayGraph::disconnect(CarlaEngine* const engine, const uint connectionI | |||
for (LinkedList<ConnectionToId>::Itenerator it=connections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connection(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
if (connection.id != connectionId) | |||
if (connectionToId.id != connectionId) | |||
continue; | |||
uint adjustedPortA = connection.portA; | |||
uint adjustedPortB = connection.portB; | |||
uint adjustedPortA = connectionToId.portA; | |||
uint adjustedPortB = connectionToId.portB; | |||
if (! adjustPatchbayPortIdForJuce(adjustedPortA)) | |||
return false; | |||
if (! adjustPatchbayPortIdForJuce(adjustedPortB)) | |||
return false; | |||
if (! graph.removeConnection(connection.groupA, static_cast<int>(adjustedPortA), | |||
connection.groupB, static_cast<int>(adjustedPortB))) | |||
if (! graph.removeConnection(connectionToId.groupA, static_cast<int>(adjustedPortA), | |||
connectionToId.groupB, static_cast<int>(adjustedPortB))) | |||
return false; | |||
engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, 0, 0, 0.0f, nullptr); | |||
engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connectionToId.id, 0, 0, 0.0f, nullptr); | |||
connections.list.remove(it); | |||
return true; | |||
@@ -1421,12 +1440,15 @@ const char* const* PatchbayGraph::getConnections() const | |||
for (LinkedList<ConnectionToId>::Itenerator it=connections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connection(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
AudioProcessorGraph::Node* const nodeA(graph.getNodeForId(connection.groupA)); | |||
AudioProcessorGraph::Node* const nodeA(graph.getNodeForId(connectionToId.groupA)); | |||
CARLA_SAFE_ASSERT_CONTINUE(nodeA != nullptr); | |||
AudioProcessorGraph::Node* const nodeB(graph.getNodeForId(connection.groupB)); | |||
AudioProcessorGraph::Node* const nodeB(graph.getNodeForId(connectionToId.groupB)); | |||
CARLA_SAFE_ASSERT_CONTINUE(nodeB != nullptr); | |||
AudioProcessor* const procA(nodeA->getProcessor()); | |||
@@ -1435,10 +1457,10 @@ const char* const* PatchbayGraph::getConnections() const | |||
AudioProcessor* const procB(nodeB->getProcessor()); | |||
CARLA_SAFE_ASSERT_CONTINUE(procB != nullptr); | |||
String fullPortNameA(getProcessorFullPortName(procA, connection.portA)); | |||
String fullPortNameA(getProcessorFullPortName(procA, connectionToId.portA)); | |||
CARLA_SAFE_ASSERT_CONTINUE(fullPortNameA.isNotEmpty()); | |||
String fullPortNameB(getProcessorFullPortName(procB, connection.portB)); | |||
String fullPortNameB(getProcessorFullPortName(procB, connectionToId.portB)); | |||
CARLA_SAFE_ASSERT_CONTINUE(fullPortNameB.isNotEmpty()); | |||
connList.append(fullPortNameA.toRawUTF8()); | |||
@@ -568,19 +568,25 @@ public: | |||
{ | |||
for (LinkedList<CarlaEngineJackAudioPort*>::Itenerator it = fAudioPorts.begin(); it.valid(); it.next()) | |||
{ | |||
CarlaEngineJackAudioPort* const port(it.getValue()); | |||
CarlaEngineJackAudioPort* const port(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != nullptr); | |||
port->invalidate(); | |||
} | |||
for (LinkedList<CarlaEngineJackCVPort*>::Itenerator it = fCVPorts.begin(); it.valid(); it.next()) | |||
{ | |||
CarlaEngineJackCVPort* const port(it.getValue()); | |||
CarlaEngineJackCVPort* const port(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != nullptr); | |||
port->invalidate(); | |||
} | |||
for (LinkedList<CarlaEngineJackEventPort*>::Itenerator it = fEventPorts.begin(); it.valid(); it.next()) | |||
{ | |||
CarlaEngineJackEventPort* const port(it.getValue()); | |||
CarlaEngineJackEventPort* const port(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(port != nullptr); | |||
port->invalidate(); | |||
} | |||
@@ -887,11 +893,11 @@ public: | |||
return; | |||
LinkedList<uint> newPlugins; | |||
fNewGroups.spliceInsertInto(newPlugins); | |||
fNewGroups.moveTo(newPlugins); | |||
for (LinkedList<uint>::Itenerator it = newPlugins.begin(); it.valid(); it.next()) | |||
{ | |||
const uint groupId(it.getValue()); | |||
const uint groupId(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupId > 0); | |||
const char* const groupName(fUsedGroups.getGroupName(groupId)); | |||
@@ -1102,7 +1108,10 @@ public: | |||
for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connectionToId(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
if (connectionToId.id == connectionId) | |||
{ | |||
@@ -1596,7 +1605,10 @@ protected: | |||
{ | |||
for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) | |||
{ | |||
const ConnectionToId& connectionToId(it.getValue()); | |||
static const ConnectionToId fallback = { 0, 0, 0, 0, 0 }; | |||
const ConnectionToId& connectionToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0); | |||
if (connectionToId.groupA == portNameToIdA.group && connectionToId.portA == portNameToIdA.port && | |||
connectionToId.groupB == portNameToIdB.group && connectionToId.portB == portNameToIdB.port) | |||
@@ -1619,9 +1631,12 @@ protected: | |||
for (LinkedList<GroupNameToId>::Itenerator it = fUsedGroups.list.begin(); it.valid(); it.next()) | |||
{ | |||
GroupNameToId& groupNameToId(it.getValue()); | |||
static GroupNameToId groupNameFallback = { 0, { '\0' } }; | |||
GroupNameToId& groupNameToId(it.getValue(groupNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (std::strcmp(groupNameToId.name, oldName) == 0) | |||
if (std::strncmp(groupNameToId.name, oldName, STR_MAX) == 0) | |||
{ | |||
groupNameToId.rename(newName); | |||
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED, groupNameToId.group, 0, 0, 0.0f, groupNameToId.name); | |||
@@ -1655,9 +1670,12 @@ protected: | |||
for (LinkedList<PortNameToId>::Itenerator it = fUsedPorts.list.begin(); it.valid(); it.next()) | |||
{ | |||
PortNameToId& portNameToId(it.getValue()); | |||
static PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
PortNameToId& portNameToId(it.getValue(portNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (std::strcmp(portNameToId.fullName, oldFullName) == 0) | |||
if (std::strncmp(portNameToId.fullName, oldFullName, STR_MAX) == 0) | |||
{ | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group == groupId); | |||
@@ -343,7 +343,9 @@ public: | |||
for (LinkedList<MidiInPort>::Itenerator it = fMidiIns.begin(); it.valid(); it.next()) | |||
{ | |||
MidiInPort& inPort(it.getValue()); | |||
static MidiInPort fallback = { nullptr, { '\0' } }; | |||
MidiInPort& inPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); | |||
inPort.port->cancelCallback(); | |||
@@ -358,7 +360,9 @@ public: | |||
for (LinkedList<MidiOutPort>::Itenerator it = fMidiOuts.begin(); it.valid(); it.next()) | |||
{ | |||
MidiOutPort& outPort(it.getValue()); | |||
static MidiOutPort fallback = { nullptr, { '\0' } }; | |||
MidiOutPort& outPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | |||
outPort.port->closePort(); | |||
@@ -516,7 +520,8 @@ public: | |||
for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn1.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& portId(it.getValue()); | |||
const uint& portId(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
ConnectionToId connectionToId; | |||
@@ -531,7 +536,8 @@ public: | |||
for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn2.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& portId(it.getValue()); | |||
const uint& portId(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
ConnectionToId connectionToId; | |||
@@ -546,7 +552,8 @@ public: | |||
for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut1.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& portId(it.getValue()); | |||
const uint& portId(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
ConnectionToId connectionToId; | |||
@@ -561,7 +568,8 @@ public: | |||
for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut2.begin(); it.valid(); it.next()) | |||
{ | |||
const uint& portId(it.getValue()); | |||
const uint& portId(it.getValue(0)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId != 0); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
ConnectionToId connectionToId; | |||
@@ -578,7 +586,10 @@ public: | |||
for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
{ | |||
const MidiInPort& inPort(it.getValue()); | |||
static const MidiInPort fallback = { nullptr, { '\0' } }; | |||
const MidiInPort& inPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); | |||
const uint portId(graph->midi.getPortId(true, inPort.name)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.ins.count()); | |||
@@ -597,7 +608,10 @@ public: | |||
for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next()) | |||
{ | |||
const MidiOutPort& outPort(it.getValue()); | |||
static const MidiOutPort fallback = { nullptr, { '\0' } }; | |||
const MidiOutPort& outPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | |||
const uint portId(graph->midi.getPortId(false, outPort.name)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.outs.count()); | |||
@@ -684,8 +698,12 @@ protected: | |||
for (LinkedList<RtMidiEvent>::Itenerator it = fMidiInEvents.data.begin(); it.valid(); it.next()) | |||
{ | |||
const RtMidiEvent& midiEvent(it.getValue()); | |||
EngineEvent& engineEvent(pData->events.in[engineEventIndex++]); | |||
static const RtMidiEvent fallback = { 0, 0, { 0 } }; | |||
const RtMidiEvent& midiEvent(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(midiEvent.size > 0); | |||
EngineEvent& engineEvent(pData->events.in[engineEventIndex++]); | |||
if (midiEvent.time < pData->timeInfo.frame) | |||
{ | |||
@@ -754,7 +772,9 @@ protected: | |||
for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next()) | |||
{ | |||
MidiOutPort& outPort(it.getValue()); | |||
static MidiOutPort fallback = { nullptr, { '\0' } }; | |||
MidiOutPort& outPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | |||
outPort.port->sendMessage(&fMidiOutVector); | |||
@@ -932,10 +952,12 @@ protected: | |||
for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
{ | |||
MidiInPort& inPort(it.getValue()); | |||
static MidiInPort fallback = { nullptr, { '\0' } }; | |||
MidiInPort& inPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); | |||
if (std::strcmp(inPort.name, portName) != 0) | |||
if (std::strncmp(inPort.name, portName, STR_MAX) != 0) | |||
continue; | |||
inPort.port->cancelCallback(); | |||
@@ -962,10 +984,12 @@ protected: | |||
for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next()) | |||
{ | |||
MidiOutPort& outPort(it.getValue()); | |||
static MidiOutPort fallback = { nullptr, { '\0' } }; | |||
MidiOutPort& outPort(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | |||
if (std::strcmp(outPort.name, portName) != 0) | |||
if (std::strncmp(outPort.name, portName, STR_MAX) != 0) | |||
continue; | |||
outPort.port->closePort(); | |||
@@ -1046,7 +1070,7 @@ private: | |||
void splice() | |||
{ | |||
dataPending.spliceAppendTo(data); | |||
dataPending.moveTo(data, true /* append */); | |||
} | |||
}; | |||
@@ -44,6 +44,8 @@ static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0 | |||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||
static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | |||
static const PluginPostRtEvent kPluginPostRtEventFallback = { kPluginPostRtEventNull, 0, 0, 0.0f }; | |||
// ------------------------------------------------------------------- | |||
// ParamSymbol struct, needed for CarlaPlugin::loadStateSave() | |||
@@ -586,7 +588,8 @@ const CarlaStateSave& CarlaPlugin::getStateSave() | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
const CustomData& cData(it.getValue()); | |||
const CustomData& cData(it.getValue(kCustomDataNull)); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.isValid()); | |||
CarlaStateSave::CustomData* stateCustomData(new CarlaStateSave::CustomData()); | |||
@@ -1194,28 +1197,25 @@ void CarlaPlugin::setCustomData(const char* const type, const char* const key, c | |||
// Check if we already have this key | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
CustomData& cData(it.getValue()); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.type != nullptr && cData.type[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.key != nullptr && cData.key[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.value != nullptr); | |||
CustomData& customData(it.getValue()); | |||
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid()); | |||
if (std::strcmp(cData.key, key) == 0) | |||
if (std::strcmp(customData.key, key) == 0) | |||
{ | |||
if (cData.value != nullptr) | |||
delete[] cData.value; | |||
if (customData.value != nullptr) | |||
delete[] customData.value; | |||
cData.value = carla_strdup(value); | |||
customData.value = carla_strdup(value); | |||
return; | |||
} | |||
} | |||
// Otherwise store it | |||
CustomData newData; | |||
newData.type = carla_strdup(type); | |||
newData.key = carla_strdup(key); | |||
newData.value = carla_strdup(value); | |||
pData->custom.append(newData); | |||
CustomData customData; | |||
customData.type = carla_strdup(type); | |||
customData.key = carla_strdup(key); | |||
customData.value = carla_strdup(value); | |||
pData->custom.append(customData); | |||
} | |||
void CarlaPlugin::setChunkData(const void* const data, const std::size_t dataSize) | |||
@@ -1617,14 +1617,11 @@ void CarlaPlugin::updateOscData(const lo_address& source, const char* const url) | |||
for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | |||
{ | |||
const CustomData& cData(it.getValue()); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.type != nullptr && cData.type[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.key != nullptr && cData.key[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(cData.value != nullptr); | |||
const CustomData& customData(it.getValue(kCustomDataNull)); | |||
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid()); | |||
if (std::strcmp(cData.type, CUSTOM_DATA_TYPE_STRING) == 0) | |||
osc_send_configure(pData->oscData, cData.key, cData.value); | |||
if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_STRING) == 0) | |||
osc_send_configure(pData->oscData, customData.key, customData.value); | |||
} | |||
if (pData->prog.current >= 0) | |||
@@ -1757,7 +1754,8 @@ void CarlaPlugin::postRtEventsRun() | |||
for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.data.begin(); it.valid(); it.next()) | |||
{ | |||
const PluginPostRtEvent& event(it.getValue()); | |||
const PluginPostRtEvent& event(it.getValue(kPluginPostRtEventFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(event.type != kPluginPostRtEventNull); | |||
switch (event.type) | |||
{ | |||
@@ -22,12 +22,12 @@ | |||
#include "CarlaPluginThread.hpp" | |||
#include "CarlaLibUtils.hpp" | |||
#include "CarlaMutex.hpp" | |||
#include "CarlaOscUtils.hpp" | |||
#include "CarlaStateUtils.hpp" | |||
#include "CarlaString.hpp" | |||
#include "CarlaMIDI.h" | |||
#include "CarlaMutex.hpp" | |||
#include "CarlaString.hpp" | |||
#include "RtLinkedList.hpp" | |||
#include "juce_audio_basics.h" | |||
@@ -50,7 +50,7 @@ struct GroupNameToId { | |||
{ | |||
if (groupNameToId.group != group) | |||
return false; | |||
if (std::strcmp(groupNameToId.name, name) != 0) | |||
if (std::strncmp(groupNameToId.name, name, STR_MAX) != 0) | |||
return false; | |||
return true; | |||
} | |||
@@ -81,9 +81,12 @@ struct PatchbayGroupList { | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const GroupNameToId& groupNameToId(it.getValue()); | |||
static const GroupNameToId groupNameFallback = { 0, { '\0' } }; | |||
if (std::strcmp(groupNameToId.name, groupName) == 0) | |||
const GroupNameToId& groupNameToId(it.getValue(groupNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (std::strncmp(groupNameToId.name, groupName, STR_MAX) == 0) | |||
return groupNameToId.group; | |||
} | |||
@@ -96,7 +99,10 @@ struct PatchbayGroupList { | |||
for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const GroupNameToId& groupNameToId(it.getValue()); | |||
static const GroupNameToId groupNameFallback = { 0, { '\0' } }; | |||
const GroupNameToId& groupNameToId(it.getValue(groupNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0); | |||
if (groupNameToId.group == groupId) | |||
return groupNameToId.name; | |||
@@ -111,7 +117,7 @@ struct PatchbayGroupList { | |||
struct PortNameToId { | |||
uint group; | |||
uint port; | |||
char name[STR_MAX+1]; // locally unique | |||
char name[STR_MAX+1]; // locally unique (within the same group) | |||
char fullName[STR_MAX+1]; // globally unique | |||
void clear() noexcept | |||
@@ -142,9 +148,9 @@ struct PortNameToId { | |||
{ | |||
if (portNameToId.group != group || portNameToId.port != port) | |||
return false; | |||
if (std::strcmp(portNameToId.name, name) != 0) | |||
if (std::strncmp(portNameToId.name, name, STR_MAX) != 0) | |||
return false; | |||
if (std::strcmp(portNameToId.fullName, fullName) != 0) | |||
if (std::strncmp(portNameToId.fullName, fullName, STR_MAX) != 0) | |||
return false; | |||
return true; | |||
} | |||
@@ -175,7 +181,10 @@ struct PatchbayPortList { | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& portNameToId(it.getValue()); | |||
static const PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } }; | |||
const PortNameToId& portNameToId(it.getValue(portNameFallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (portNameToId.group == groupId && portNameToId.port == portId) | |||
return portNameToId.fullName; | |||
@@ -192,9 +201,10 @@ struct PatchbayPortList { | |||
for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
const PortNameToId& portNameToId(it.getValue()); | |||
const PortNameToId& portNameToId(it.getValue(fallback)); | |||
CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0); | |||
if (std::strcmp(portNameToId.fullName, fullPortName) == 0) | |||
if (std::strncmp(portNameToId.fullName, fullPortName, STR_MAX) == 0) | |||
return portNameToId; | |||
} | |||
@@ -162,6 +162,14 @@ CarlaStateSave::CustomData::~CustomData() noexcept | |||
} | |||
} | |||
bool CarlaStateSave::CustomData::isValid() const noexcept | |||
{ | |||
if (type == nullptr || type[0] == '\0') return false; | |||
if (key == nullptr || key [0] == '\0') return false; | |||
if (value == nullptr) return false; | |||
return true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// StateSave | |||
@@ -244,13 +252,13 @@ void CarlaStateSave::clear() noexcept | |||
for (ParameterItenerator it = parameters.begin(); it.valid(); it.next()) | |||
{ | |||
Parameter* const stateParameter(it.getValue()); | |||
Parameter* const stateParameter(it.getValue(nullptr)); | |||
delete stateParameter; | |||
} | |||
for (CustomDataItenerator it = customData.begin(); it.valid(); it.next()) | |||
{ | |||
CustomData* const stateCustomData(it.getValue()); | |||
CustomData* const stateCustomData(it.getValue(nullptr)); | |||
delete stateCustomData; | |||
} | |||
@@ -451,7 +459,10 @@ bool CarlaStateSave::fillFromXmlElement(const XmlElement* const xmlElement) | |||
stateCustomData->value = carla_strdup(cText.toRawUTF8()); //xmlSafeStringCharDup(cText, false); | |||
} | |||
customData.append(stateCustomData); | |||
if (stateCustomData->isValid()) | |||
customData.append(stateCustomData); | |||
else | |||
carla_stderr("Reading CustomData property failed, missing data"); | |||
} | |||
// ------------------------------------------------------- | |||
@@ -559,7 +570,8 @@ String CarlaStateSave::toString() const | |||
for (ParameterItenerator it = parameters.begin(); it.valid(); it.next()) | |||
{ | |||
Parameter* const stateParameter(it.getValue()); | |||
Parameter* const stateParameter(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateParameter != nullptr); | |||
String parameterXml("\n"" <Parameter>\n"); | |||
@@ -609,10 +621,9 @@ String CarlaStateSave::toString() const | |||
for (CustomDataItenerator it = customData.begin(); it.valid(); it.next()) | |||
{ | |||
CustomData* const stateCustomData(it.getValue()); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->type != nullptr && stateCustomData->type[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->key != nullptr && stateCustomData->key[0] != '\0'); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->value != nullptr); | |||
CustomData* const stateCustomData(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr); | |||
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid()); | |||
String customDataXml("\n"" <CustomData>\n"); | |||
customDataXml << " <Type>" << xmlSafeString(stateCustomData->type, true) << "</Type>\n"; | |||
@@ -55,6 +55,7 @@ struct CarlaStateSave { | |||
CustomData() noexcept; | |||
~CustomData() noexcept; | |||
bool isValid() const noexcept; | |||
CARLA_DECLARE_NON_COPY_STRUCT(CustomData) | |||
}; | |||
@@ -136,7 +136,7 @@ protected: | |||
std::size_t i=0; | |||
for (LinkedList<const char*>::Itenerator it = list.begin(); it.valid(); it.next(), ++i) | |||
{ | |||
tmpList[i] = carla_strdup_safe(it.getValue()); | |||
tmpList[i] = carla_strdup_safe(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_BREAK(tmpList[i] != nullptr); | |||
} | |||
CARLA_SAFE_ASSERT(i == count); | |||
@@ -163,7 +163,7 @@ public: | |||
: LinkedList<const char*>() | |||
{ | |||
for (Itenerator it = list.begin(); it.valid(); it.next()) | |||
LinkedList<const char*>::append(carla_strdup_safe(it.getValue())); | |||
LinkedList<const char*>::append(carla_strdup_safe(it.getValue(nullptr))); | |||
} | |||
~CarlaStringList() noexcept override | |||
@@ -177,7 +177,7 @@ public: | |||
{ | |||
for (Itenerator it = begin(); it.valid(); it.next()) | |||
{ | |||
if (const char* const string = it.getValue()) | |||
if (const char* const string = it.getValue(nullptr)) | |||
delete[] string; | |||
} | |||
@@ -246,7 +246,7 @@ public: | |||
void remove(Itenerator& it) noexcept | |||
{ | |||
if (const char* const string = it.getValue()) | |||
if (const char* const string = it.getValue(nullptr)) | |||
delete[] string; | |||
LinkedList<const char*>::remove(it); | |||
@@ -258,7 +258,7 @@ public: | |||
for (Itenerator it = begin(); it.valid(); it.next()) | |||
{ | |||
const char* const stringComp(it.getValue()); | |||
const char* const stringComp(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stringComp != nullptr); | |||
if (std::strcmp(string, stringComp) != 0) | |||
@@ -278,7 +278,7 @@ public: | |||
for (Itenerator it = begin(); it.valid(); it.next()) | |||
{ | |||
const char* const stringComp(it.getValue()); | |||
const char* const stringComp(it.getValue(nullptr)); | |||
CARLA_SAFE_ASSERT_CONTINUE(stringComp != nullptr); | |||
if (std::strcmp(string, stringComp) != 0) | |||
@@ -317,7 +317,7 @@ public: | |||
for (Itenerator it = list.begin(); it.valid(); it.next()) | |||
{ | |||
if (const char* const string = carla_strdup_safe(it.getValue())) | |||
if (const char* const string = carla_strdup_safe(it.getValue(nullptr))) | |||
LinkedList<const char*>::append(string); | |||
} | |||
@@ -86,8 +86,7 @@ public: | |||
class Itenerator { | |||
public: | |||
Itenerator(const ListHead& queue) noexcept | |||
: fData(nullptr), | |||
fEntry(queue.next), | |||
: fEntry(queue.next), | |||
fEntry2(fEntry->next), | |||
kQueue(queue) | |||
{ | |||
@@ -106,20 +105,31 @@ public: | |||
fEntry2 = (fEntry != nullptr) ? fEntry->next : nullptr; | |||
} | |||
T& getValue() noexcept | |||
T& getValue(T& fallback) const noexcept | |||
{ | |||
fData = list_entry(fEntry, Data, siblings); | |||
return fData->value; | |||
Data* const data(list_entry(fEntry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
return data->value; | |||
} | |||
const T& getValue(const T& fallback) const noexcept | |||
{ | |||
const Data* const data(list_entry_const(fEntry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
return data->value; | |||
} | |||
void setValue(const T& value) noexcept | |||
{ | |||
fData = list_entry(fEntry, Data, siblings); | |||
fData->value = value; | |||
Data* const data(list_entry(fEntry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | |||
data->value = value; | |||
} | |||
private: | |||
Data* fData; | |||
ListHead* fEntry; | |||
ListHead* fEntry2; | |||
const ListHead& kQueue; | |||
@@ -137,12 +147,9 @@ public: | |||
if (fCount == 0) | |||
return; | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
Data* const data = list_entry(entry, Data, siblings); | |||
Data* const data(list_entry(entry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | |||
_deallocate(data); | |||
@@ -181,20 +188,18 @@ public: | |||
return _add(value, false, it.fEntry->prev); | |||
} | |||
const T& getAt(const std::size_t index, const T& fallback) const noexcept | |||
T getAt(const std::size_t index, T& fallback, const bool removeObj) noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
std::size_t i = 0; | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
if (index != i++) | |||
continue; | |||
return _get(entry, fallback); | |||
return _get(entry, fallback, removeObj); | |||
} | |||
return fallback; | |||
@@ -205,10 +210,8 @@ public: | |||
CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
std::size_t i = 0; | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
if (index != i++) | |||
continue; | |||
@@ -219,20 +222,18 @@ public: | |||
return fallback; | |||
} | |||
T getAt(const std::size_t index, T& fallback, const bool removeObj) noexcept | |||
const T& getAt(const std::size_t index, const T& fallback) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
std::size_t i = 0; | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
if (index != i++) | |||
continue; | |||
return _get(entry, fallback, removeObj); | |||
return _get(entry, fallback); | |||
} | |||
return fallback; | |||
@@ -283,17 +284,16 @@ public: | |||
void remove(Itenerator& it) noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(it.fEntry != nullptr,); | |||
CARLA_SAFE_ASSERT_RETURN(it.fData != nullptr,); | |||
_delete(it.fEntry, it.fData); | |||
Data* const data(list_entry(it.fEntry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | |||
_delete(it.fEntry, data); | |||
} | |||
bool removeOne(const T& value) noexcept | |||
{ | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
Data* const data = list_entry(entry, Data, siblings); | |||
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | |||
@@ -311,10 +311,7 @@ public: | |||
void removeAll(const T& value) noexcept | |||
{ | |||
ListHead* entry; | |||
ListHead* entry2; | |||
for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
{ | |||
Data* const data = list_entry(entry, Data, siblings); | |||
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | |||
@@ -326,25 +323,20 @@ public: | |||
} | |||
} | |||
void spliceAppendTo(AbstractLinkedList<T>& list) noexcept | |||
// move data to a new list, and clear ourselves | |||
void moveTo(AbstractLinkedList<T>& list, const bool inTail = true) noexcept | |||
{ | |||
if (fQueue.next == &fQueue) | |||
return; | |||
CARLA_SAFE_ASSERT_RETURN(fCount > 0,); | |||
__list_splice_tail(&fQueue, &list.fQueue); | |||
list.fCount += fCount; | |||
_init(); | |||
} | |||
if (inTail) | |||
__list_splice_tail(&fQueue, &list.fQueue); | |||
else | |||
__list_splice(&fQueue, &list.fQueue); | |||
void spliceInsertInto(AbstractLinkedList<T>& list) noexcept | |||
{ | |||
if (fQueue.next == &fQueue) | |||
return; | |||
__list_splice(&fQueue, &list.fQueue); | |||
//! @a list gets our items | |||
list.fCount += fCount; | |||
//! and we get nothing | |||
_init(); | |||
} | |||
@@ -365,59 +357,63 @@ private: | |||
fQueue.prev = &fQueue; | |||
} | |||
void _createData(Data* const data, const T& value) noexcept | |||
bool _add(const T& value, const bool inTail, ListHead* const queue) noexcept | |||
{ | |||
++fCount; | |||
data->value = value; | |||
//std::memcpy(data->value, value, kDataSize); | |||
return _add_internal(_allocate(), value, inTail, queue); | |||
} | |||
bool _add(const T& value, const bool inTail, ListHead* const queue) noexcept | |||
bool _add_internal(Data* const data, const T& value, const bool inTail, ListHead* const queue) noexcept | |||
{ | |||
if (Data* const data = _allocate()) | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
CARLA_SAFE_ASSERT_RETURN(queue != nullptr, false); | |||
CARLA_SAFE_ASSERT_RETURN(queue->prev != nullptr, false); | |||
CARLA_SAFE_ASSERT_RETURN(queue->next != nullptr, false); | |||
data->value = value; | |||
ListHead* const siblings(&data->siblings); | |||
if (inTail) | |||
{ | |||
_createData(data, value); | |||
siblings->prev = queue->prev; | |||
siblings->next = queue; | |||
if (inTail) | |||
__list_add(data->siblings, queue->prev, queue); | |||
else | |||
__list_add(data->siblings, queue, queue->next); | |||
queue->prev->next = siblings; | |||
queue->prev = siblings; | |||
} | |||
else | |||
{ | |||
siblings->prev = queue; | |||
siblings->next = queue->next; | |||
return true; | |||
queue->next->prev = siblings; | |||
queue->next = siblings; | |||
} | |||
return false; | |||
++fCount; | |||
return true; | |||
} | |||
void _delete(ListHead* const entry, Data* const data) noexcept | |||
{ | |||
__list_del(entry->prev, entry->next); | |||
entry->next = nullptr; | |||
entry->prev = nullptr; | |||
CARLA_SAFE_ASSERT_RETURN(entry != nullptr,); | |||
CARLA_SAFE_ASSERT_RETURN(entry->prev != nullptr,); | |||
CARLA_SAFE_ASSERT_RETURN(entry->next != nullptr,); | |||
_deallocate(data); | |||
--fCount; | |||
} | |||
const T& _get(ListHead* const entry, const T& fallback) const noexcept | |||
{ | |||
const Data* const data = list_entry_const(entry, Data, siblings); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
return data->value; | |||
} | |||
entry->next->prev = entry->prev; | |||
entry->prev->next = entry->next; | |||
T& _get(ListHead* const entry, T& fallback) const noexcept | |||
{ | |||
Data* const data = list_entry(entry, Data, siblings); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
entry->next = nullptr; | |||
entry->prev = nullptr; | |||
return data->value; | |||
_deallocate(data); | |||
} | |||
T _get(ListHead* const entry, T& fallback, const bool removeObj) noexcept | |||
{ | |||
Data* const data = list_entry(entry, Data, siblings); | |||
Data* const data(list_entry(entry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
if (! removeObj) | |||
@@ -430,25 +426,20 @@ private: | |||
return value; | |||
} | |||
/* | |||
* Insert a new entry between two known consecutive entries. | |||
*/ | |||
static void __list_add(ListHead& newl, ListHead* const prev, ListHead* const next) noexcept | |||
T& _get(ListHead* const entry, T& fallback) const noexcept | |||
{ | |||
next->prev = &newl; | |||
newl.next = next; | |||
newl.prev = prev; | |||
prev->next = &newl; | |||
Data* const data(list_entry(entry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
return data->value; | |||
} | |||
/* | |||
* Delete a list entry by making the prev/next entries | |||
* point to each other. | |||
*/ | |||
static void __list_del(ListHead* const prev, ListHead* const next) noexcept | |||
const T& _get(ListHead* const entry, const T& fallback) const noexcept | |||
{ | |||
next->prev = prev; | |||
prev->next = next; | |||
const Data* const data(list_entry_const(entry, Data, siblings)); | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
return data->value; | |||
} | |||
static void __list_splice(ListHead* const list, ListHead* const head) noexcept | |||
@@ -500,8 +491,6 @@ protected: | |||
void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||
std::free(dataPtr); | |||
} | |||
@@ -37,9 +37,9 @@ public: | |||
class Pool | |||
{ | |||
public: | |||
Pool(const size_t minPreallocated, const size_t maxPreallocated) noexcept | |||
: fHandle(nullptr), | |||
kDataSize(sizeof(typename AbstractLinkedList<T>::Data)) | |||
Pool(const std::size_t minPreallocated, const std::size_t maxPreallocated) noexcept | |||
: kDataSize(sizeof(typename AbstractLinkedList<T>::Data)), | |||
fHandle(nullptr) | |||
{ | |||
resize(minPreallocated, maxPreallocated); | |||
} | |||
@@ -65,10 +65,12 @@ public: | |||
void deallocate(void* const dataPtr) const noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||
rtsafe_memory_pool_deallocate(fHandle, dataPtr); | |||
} | |||
void resize(const size_t minPreallocated, const size_t maxPreallocated) noexcept | |||
void resize(const std::size_t minPreallocated, const std::size_t maxPreallocated) noexcept | |||
{ | |||
if (fHandle != nullptr) | |||
{ | |||
@@ -91,8 +93,9 @@ public: | |||
} | |||
private: | |||
const std::size_t kDataSize; | |||
mutable RtMemPool_Handle fHandle; | |||
const size_t kDataSize; | |||
CARLA_PREVENT_HEAP_ALLOCATION | |||
CARLA_DECLARE_NON_COPY_CLASS(Pool) | |||
@@ -114,25 +117,19 @@ public: | |||
return _add_sleepy(value, false); | |||
} | |||
void resize(const size_t minPreallocated, const size_t maxPreallocated) noexcept | |||
void resize(const std::size_t minPreallocated, const std::size_t maxPreallocated) noexcept | |||
{ | |||
CARLA_SAFE_ASSERT(this->fCount == 0); | |||
this->clear(); | |||
fMemPool.resize(minPreallocated, maxPreallocated); | |||
} | |||
void spliceAppendTo(RtLinkedList<T>& list) noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,); | |||
AbstractLinkedList<T>::spliceAppendTo(list); | |||
} | |||
void spliceInsertInto(RtLinkedList<T>& list) noexcept | |||
void moveTo(RtLinkedList<T>& list, const bool inTail) noexcept | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,); | |||
AbstractLinkedList<T>::spliceInsertInto(list); | |||
AbstractLinkedList<T>::moveTo(list, inTail); | |||
} | |||
protected: | |||
@@ -148,8 +145,6 @@ protected: | |||
void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||
fMemPool.deallocate(dataPtr); | |||
} | |||
@@ -158,19 +153,7 @@ private: | |||
bool _add_sleepy(const T& value, const bool inTail) noexcept | |||
{ | |||
if (typename AbstractLinkedList<T>::Data* const data = _allocate_sleepy()) | |||
{ | |||
this->_createData(data, value); | |||
if (inTail) | |||
this->__list_add(data->siblings, this->fQueue.prev, &(this->fQueue)); | |||
else | |||
this->__list_add(data->siblings, &(this->fQueue), this->fQueue.next); | |||
return true; | |||
} | |||
return false; | |||
return this->_add_internal(_allocate_sleepy(), value, inTail, &this->fQueue); | |||
} | |||
CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION | |||