| @@ -1423,6 +1423,19 @@ typedef struct { | |||||
| */ | */ | ||||
| const char* value; | 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; | } 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()) | 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; | 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()) | 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) | if (ok != nullptr) | ||||
| *ok = true; | *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()) | 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; | continue; | ||||
| uint otherGroup, otherPort, carlaPort; | 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 | 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); | 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; | 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); | connections.list.remove(it); | ||||
| return true; | 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()) | 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; | 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 | 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); | 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 | // connect input buffers | ||||
| for (LinkedList<uint>::Itenerator it = audio.connectedIn1.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(port < inputs); | ||||
| if (noConnections) | 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()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(port < inputs); | ||||
| if (noConnections) | 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()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(port < outputs); | ||||
| FloatVectorOperations::add(outBuf[port], audio.outBuf[0], iframes); | 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()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(port < outputs); | ||||
| FloatVectorOperations::add(outBuf[port], audio.outBuf[1], iframes); | 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()) | 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; | continue; | ||||
| uint adjustedPortA = connection.portA; | |||||
| uint adjustedPortB = connection.portB; | |||||
| uint adjustedPortA = connectionToId.portA; | |||||
| uint adjustedPortB = connectionToId.portB; | |||||
| if (! adjustPatchbayPortIdForJuce(adjustedPortA)) | if (! adjustPatchbayPortIdForJuce(adjustedPortA)) | ||||
| return false; | return false; | ||||
| if (! adjustPatchbayPortIdForJuce(adjustedPortB)) | if (! adjustPatchbayPortIdForJuce(adjustedPortB)) | ||||
| return false; | 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; | 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); | connections.list.remove(it); | ||||
| return true; | return true; | ||||
| @@ -1421,12 +1440,15 @@ const char* const* PatchbayGraph::getConnections() const | |||||
| for (LinkedList<ConnectionToId>::Itenerator it=connections.list.begin(); it.valid(); it.next()) | 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); | 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); | CARLA_SAFE_ASSERT_CONTINUE(nodeB != nullptr); | ||||
| AudioProcessor* const procA(nodeA->getProcessor()); | AudioProcessor* const procA(nodeA->getProcessor()); | ||||
| @@ -1435,10 +1457,10 @@ const char* const* PatchbayGraph::getConnections() const | |||||
| AudioProcessor* const procB(nodeB->getProcessor()); | AudioProcessor* const procB(nodeB->getProcessor()); | ||||
| CARLA_SAFE_ASSERT_CONTINUE(procB != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(procB != nullptr); | ||||
| String fullPortNameA(getProcessorFullPortName(procA, connection.portA)); | |||||
| String fullPortNameA(getProcessorFullPortName(procA, connectionToId.portA)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(fullPortNameA.isNotEmpty()); | CARLA_SAFE_ASSERT_CONTINUE(fullPortNameA.isNotEmpty()); | ||||
| String fullPortNameB(getProcessorFullPortName(procB, connection.portB)); | |||||
| String fullPortNameB(getProcessorFullPortName(procB, connectionToId.portB)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(fullPortNameB.isNotEmpty()); | CARLA_SAFE_ASSERT_CONTINUE(fullPortNameB.isNotEmpty()); | ||||
| connList.append(fullPortNameA.toRawUTF8()); | connList.append(fullPortNameA.toRawUTF8()); | ||||
| @@ -568,19 +568,25 @@ public: | |||||
| { | { | ||||
| for (LinkedList<CarlaEngineJackAudioPort*>::Itenerator it = fAudioPorts.begin(); it.valid(); it.next()) | 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(); | port->invalidate(); | ||||
| } | } | ||||
| for (LinkedList<CarlaEngineJackCVPort*>::Itenerator it = fCVPorts.begin(); it.valid(); it.next()) | 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(); | port->invalidate(); | ||||
| } | } | ||||
| for (LinkedList<CarlaEngineJackEventPort*>::Itenerator it = fEventPorts.begin(); it.valid(); it.next()) | 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(); | port->invalidate(); | ||||
| } | } | ||||
| @@ -887,11 +893,11 @@ public: | |||||
| return; | return; | ||||
| LinkedList<uint> newPlugins; | LinkedList<uint> newPlugins; | ||||
| fNewGroups.spliceInsertInto(newPlugins); | |||||
| fNewGroups.moveTo(newPlugins); | |||||
| for (LinkedList<uint>::Itenerator it = newPlugins.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(groupId > 0); | ||||
| const char* const groupName(fUsedGroups.getGroupName(groupId)); | const char* const groupName(fUsedGroups.getGroupName(groupId)); | ||||
| @@ -1102,7 +1108,10 @@ public: | |||||
| for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) | 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) | if (connectionToId.id == connectionId) | ||||
| { | { | ||||
| @@ -1596,7 +1605,10 @@ protected: | |||||
| { | { | ||||
| for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) | 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 && | if (connectionToId.groupA == portNameToIdA.group && connectionToId.portA == portNameToIdA.port && | ||||
| connectionToId.groupB == portNameToIdB.group && connectionToId.portB == portNameToIdB.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()) | 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); | groupNameToId.rename(newName); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED, groupNameToId.group, 0, 0, 0.0f, groupNameToId.name); | 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()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group == groupId); | ||||
| @@ -343,7 +343,9 @@ public: | |||||
| for (LinkedList<MidiInPort>::Itenerator it = fMidiIns.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); | ||||
| inPort.port->cancelCallback(); | inPort.port->cancelCallback(); | ||||
| @@ -358,7 +360,9 @@ public: | |||||
| for (LinkedList<MidiOutPort>::Itenerator it = fMidiOuts.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | ||||
| outPort.port->closePort(); | outPort.port->closePort(); | ||||
| @@ -516,7 +520,8 @@ public: | |||||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn1.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | ||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| @@ -531,7 +536,8 @@ public: | |||||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn2.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | ||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| @@ -546,7 +552,8 @@ public: | |||||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut1.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | ||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| @@ -561,7 +568,8 @@ public: | |||||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut2.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | ||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| @@ -578,7 +586,10 @@ public: | |||||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | 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)); | const uint portId(graph->midi.getPortId(true, inPort.name)); | ||||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.ins.count()); | 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()) | 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)); | const uint portId(graph->midi.getPortId(false, outPort.name)); | ||||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.outs.count()); | 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()) | 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) | if (midiEvent.time < pData->timeInfo.frame) | ||||
| { | { | ||||
| @@ -754,7 +772,9 @@ protected: | |||||
| for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | ||||
| outPort.port->sendMessage(&fMidiOutVector); | outPort.port->sendMessage(&fMidiOutVector); | ||||
| @@ -932,10 +952,12 @@ protected: | |||||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(inPort.port != nullptr); | ||||
| if (std::strcmp(inPort.name, portName) != 0) | |||||
| if (std::strncmp(inPort.name, portName, STR_MAX) != 0) | |||||
| continue; | continue; | ||||
| inPort.port->cancelCallback(); | inPort.port->cancelCallback(); | ||||
| @@ -962,10 +984,12 @@ protected: | |||||
| for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(outPort.port != nullptr); | ||||
| if (std::strcmp(outPort.name, portName) != 0) | |||||
| if (std::strncmp(outPort.name, portName, STR_MAX) != 0) | |||||
| continue; | continue; | ||||
| outPort.port->closePort(); | outPort.port->closePort(); | ||||
| @@ -1046,7 +1070,7 @@ private: | |||||
| void splice() | 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 MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | ||||
| static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | ||||
| static const PluginPostRtEvent kPluginPostRtEventFallback = { kPluginPostRtEventNull, 0, 0, 0.0f }; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // ParamSymbol struct, needed for CarlaPlugin::loadStateSave() | // 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()) | 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()); | 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 | // Check if we already have this key | ||||
| for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next()) | 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; | return; | ||||
| } | } | ||||
| } | } | ||||
| // Otherwise store it | // 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) | 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()) | 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) | 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()) | 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) | switch (event.type) | ||||
| { | { | ||||
| @@ -22,12 +22,12 @@ | |||||
| #include "CarlaPluginThread.hpp" | #include "CarlaPluginThread.hpp" | ||||
| #include "CarlaLibUtils.hpp" | #include "CarlaLibUtils.hpp" | ||||
| #include "CarlaMutex.hpp" | |||||
| #include "CarlaOscUtils.hpp" | #include "CarlaOscUtils.hpp" | ||||
| #include "CarlaStateUtils.hpp" | #include "CarlaStateUtils.hpp" | ||||
| #include "CarlaString.hpp" | |||||
| #include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
| #include "CarlaMutex.hpp" | |||||
| #include "CarlaString.hpp" | |||||
| #include "RtLinkedList.hpp" | #include "RtLinkedList.hpp" | ||||
| #include "juce_audio_basics.h" | #include "juce_audio_basics.h" | ||||
| @@ -50,7 +50,7 @@ struct GroupNameToId { | |||||
| { | { | ||||
| if (groupNameToId.group != group) | if (groupNameToId.group != group) | ||||
| return false; | return false; | ||||
| if (std::strcmp(groupNameToId.name, name) != 0) | |||||
| if (std::strncmp(groupNameToId.name, name, STR_MAX) != 0) | |||||
| return false; | return false; | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -81,9 +81,12 @@ struct PatchbayGroupList { | |||||
| for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | 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; | return groupNameToId.group; | ||||
| } | } | ||||
| @@ -96,7 +99,10 @@ struct PatchbayGroupList { | |||||
| for (LinkedList<GroupNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | 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) | if (groupNameToId.group == groupId) | ||||
| return groupNameToId.name; | return groupNameToId.name; | ||||
| @@ -111,7 +117,7 @@ struct PatchbayGroupList { | |||||
| struct PortNameToId { | struct PortNameToId { | ||||
| uint group; | uint group; | ||||
| uint port; | 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 | char fullName[STR_MAX+1]; // globally unique | ||||
| void clear() noexcept | void clear() noexcept | ||||
| @@ -142,9 +148,9 @@ struct PortNameToId { | |||||
| { | { | ||||
| if (portNameToId.group != group || portNameToId.port != port) | if (portNameToId.group != group || portNameToId.port != port) | ||||
| return false; | return false; | ||||
| if (std::strcmp(portNameToId.name, name) != 0) | |||||
| if (std::strncmp(portNameToId.name, name, STR_MAX) != 0) | |||||
| return false; | return false; | ||||
| if (std::strcmp(portNameToId.fullName, fullName) != 0) | |||||
| if (std::strncmp(portNameToId.fullName, fullName, STR_MAX) != 0) | |||||
| return false; | return false; | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -175,7 +181,10 @@ struct PatchbayPortList { | |||||
| for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | 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) | if (portNameToId.group == groupId && portNameToId.port == portId) | ||||
| return portNameToId.fullName; | return portNameToId.fullName; | ||||
| @@ -192,9 +201,10 @@ struct PatchbayPortList { | |||||
| for (LinkedList<PortNameToId>::Itenerator it = list.begin(); it.valid(); it.next()) | 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; | 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 | // StateSave | ||||
| @@ -244,13 +252,13 @@ void CarlaStateSave::clear() noexcept | |||||
| for (ParameterItenerator it = parameters.begin(); it.valid(); it.next()) | for (ParameterItenerator it = parameters.begin(); it.valid(); it.next()) | ||||
| { | { | ||||
| Parameter* const stateParameter(it.getValue()); | |||||
| Parameter* const stateParameter(it.getValue(nullptr)); | |||||
| delete stateParameter; | delete stateParameter; | ||||
| } | } | ||||
| for (CustomDataItenerator it = customData.begin(); it.valid(); it.next()) | for (CustomDataItenerator it = customData.begin(); it.valid(); it.next()) | ||||
| { | { | ||||
| CustomData* const stateCustomData(it.getValue()); | |||||
| CustomData* const stateCustomData(it.getValue(nullptr)); | |||||
| delete stateCustomData; | delete stateCustomData; | ||||
| } | } | ||||
| @@ -451,7 +459,10 @@ bool CarlaStateSave::fillFromXmlElement(const XmlElement* const xmlElement) | |||||
| stateCustomData->value = carla_strdup(cText.toRawUTF8()); //xmlSafeStringCharDup(cText, false); | 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()) | 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"); | String parameterXml("\n"" <Parameter>\n"); | ||||
| @@ -609,10 +621,9 @@ String CarlaStateSave::toString() const | |||||
| for (CustomDataItenerator it = customData.begin(); it.valid(); it.next()) | 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"); | String customDataXml("\n"" <CustomData>\n"); | ||||
| customDataXml << " <Type>" << xmlSafeString(stateCustomData->type, true) << "</Type>\n"; | customDataXml << " <Type>" << xmlSafeString(stateCustomData->type, true) << "</Type>\n"; | ||||
| @@ -55,6 +55,7 @@ struct CarlaStateSave { | |||||
| CustomData() noexcept; | CustomData() noexcept; | ||||
| ~CustomData() noexcept; | ~CustomData() noexcept; | ||||
| bool isValid() const noexcept; | |||||
| CARLA_DECLARE_NON_COPY_STRUCT(CustomData) | CARLA_DECLARE_NON_COPY_STRUCT(CustomData) | ||||
| }; | }; | ||||
| @@ -136,7 +136,7 @@ protected: | |||||
| std::size_t i=0; | std::size_t i=0; | ||||
| for (LinkedList<const char*>::Itenerator it = list.begin(); it.valid(); it.next(), ++i) | 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_BREAK(tmpList[i] != nullptr); | ||||
| } | } | ||||
| CARLA_SAFE_ASSERT(i == count); | CARLA_SAFE_ASSERT(i == count); | ||||
| @@ -163,7 +163,7 @@ public: | |||||
| : LinkedList<const char*>() | : LinkedList<const char*>() | ||||
| { | { | ||||
| for (Itenerator it = list.begin(); it.valid(); it.next()) | 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 | ~CarlaStringList() noexcept override | ||||
| @@ -177,7 +177,7 @@ public: | |||||
| { | { | ||||
| for (Itenerator it = begin(); it.valid(); it.next()) | 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; | delete[] string; | ||||
| } | } | ||||
| @@ -246,7 +246,7 @@ public: | |||||
| void remove(Itenerator& it) noexcept | void remove(Itenerator& it) noexcept | ||||
| { | { | ||||
| if (const char* const string = it.getValue()) | |||||
| if (const char* const string = it.getValue(nullptr)) | |||||
| delete[] string; | delete[] string; | ||||
| LinkedList<const char*>::remove(it); | LinkedList<const char*>::remove(it); | ||||
| @@ -258,7 +258,7 @@ public: | |||||
| for (Itenerator it = begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(stringComp != nullptr); | ||||
| if (std::strcmp(string, stringComp) != 0) | if (std::strcmp(string, stringComp) != 0) | ||||
| @@ -278,7 +278,7 @@ public: | |||||
| for (Itenerator it = begin(); it.valid(); it.next()) | 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); | CARLA_SAFE_ASSERT_CONTINUE(stringComp != nullptr); | ||||
| if (std::strcmp(string, stringComp) != 0) | if (std::strcmp(string, stringComp) != 0) | ||||
| @@ -317,7 +317,7 @@ public: | |||||
| for (Itenerator it = list.begin(); it.valid(); it.next()) | 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); | LinkedList<const char*>::append(string); | ||||
| } | } | ||||
| @@ -86,8 +86,7 @@ public: | |||||
| class Itenerator { | class Itenerator { | ||||
| public: | public: | ||||
| Itenerator(const ListHead& queue) noexcept | Itenerator(const ListHead& queue) noexcept | ||||
| : fData(nullptr), | |||||
| fEntry(queue.next), | |||||
| : fEntry(queue.next), | |||||
| fEntry2(fEntry->next), | fEntry2(fEntry->next), | ||||
| kQueue(queue) | kQueue(queue) | ||||
| { | { | ||||
| @@ -106,20 +105,31 @@ public: | |||||
| fEntry2 = (fEntry != nullptr) ? fEntry->next : nullptr; | 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 | 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: | private: | ||||
| Data* fData; | |||||
| ListHead* fEntry; | ListHead* fEntry; | ||||
| ListHead* fEntry2; | ListHead* fEntry2; | ||||
| const ListHead& kQueue; | const ListHead& kQueue; | ||||
| @@ -137,12 +147,9 @@ public: | |||||
| if (fCount == 0) | if (fCount == 0) | ||||
| return; | 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); | CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | ||||
| _deallocate(data); | _deallocate(data); | ||||
| @@ -181,20 +188,18 @@ public: | |||||
| return _add(value, false, it.fEntry->prev); | 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); | CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | ||||
| std::size_t i = 0; | 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++) | if (index != i++) | ||||
| continue; | continue; | ||||
| return _get(entry, fallback); | |||||
| return _get(entry, fallback, removeObj); | |||||
| } | } | ||||
| return fallback; | return fallback; | ||||
| @@ -205,10 +210,8 @@ public: | |||||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | ||||
| std::size_t i = 0; | 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++) | if (index != i++) | ||||
| continue; | continue; | ||||
| @@ -219,20 +222,18 @@ public: | |||||
| return fallback; | 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); | CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | ||||
| std::size_t i = 0; | 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++) | if (index != i++) | ||||
| continue; | continue; | ||||
| return _get(entry, fallback, removeObj); | |||||
| return _get(entry, fallback); | |||||
| } | } | ||||
| return fallback; | return fallback; | ||||
| @@ -283,17 +284,16 @@ public: | |||||
| void remove(Itenerator& it) noexcept | void remove(Itenerator& it) noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(it.fEntry != nullptr,); | 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 | 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); | Data* const data = list_entry(entry, Data, siblings); | ||||
| CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | ||||
| @@ -311,10 +311,7 @@ public: | |||||
| void removeAll(const T& value) noexcept | 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); | Data* const data = list_entry(entry, Data, siblings); | ||||
| CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | 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; | list.fCount += fCount; | ||||
| //! and we get nothing | |||||
| _init(); | _init(); | ||||
| } | } | ||||
| @@ -365,59 +357,63 @@ private: | |||||
| fQueue.prev = &fQueue; | 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 | 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; | --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 | 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); | CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | ||||
| if (! removeObj) | if (! removeObj) | ||||
| @@ -430,25 +426,20 @@ private: | |||||
| return value; | 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 | 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 | void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||||
| std::free(dataPtr); | std::free(dataPtr); | ||||
| } | } | ||||
| @@ -37,9 +37,9 @@ public: | |||||
| class Pool | class Pool | ||||
| { | { | ||||
| public: | 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); | resize(minPreallocated, maxPreallocated); | ||||
| } | } | ||||
| @@ -65,10 +65,12 @@ public: | |||||
| void deallocate(void* const dataPtr) const noexcept | void deallocate(void* const dataPtr) const noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||||
| rtsafe_memory_pool_deallocate(fHandle, dataPtr); | 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) | if (fHandle != nullptr) | ||||
| { | { | ||||
| @@ -91,8 +93,9 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| const std::size_t kDataSize; | |||||
| mutable RtMemPool_Handle fHandle; | mutable RtMemPool_Handle fHandle; | ||||
| const size_t kDataSize; | |||||
| CARLA_PREVENT_HEAP_ALLOCATION | CARLA_PREVENT_HEAP_ALLOCATION | ||||
| CARLA_DECLARE_NON_COPY_CLASS(Pool) | CARLA_DECLARE_NON_COPY_CLASS(Pool) | ||||
| @@ -114,25 +117,19 @@ public: | |||||
| return _add_sleepy(value, false); | 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(); | this->clear(); | ||||
| fMemPool.resize(minPreallocated, maxPreallocated); | 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,); | CARLA_SAFE_ASSERT_RETURN(fMemPool == list.fMemPool,); | ||||
| AbstractLinkedList<T>::spliceInsertInto(list); | |||||
| AbstractLinkedList<T>::moveTo(list, inTail); | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -148,8 +145,6 @@ protected: | |||||
| void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override | void _deallocate(typename AbstractLinkedList<T>::Data* const dataPtr) noexcept override | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr,); | |||||
| fMemPool.deallocate(dataPtr); | fMemPool.deallocate(dataPtr); | ||||
| } | } | ||||
| @@ -158,19 +153,7 @@ private: | |||||
| bool _add_sleepy(const T& value, const bool inTail) noexcept | 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 | CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION | ||||