| @@ -144,7 +144,7 @@ const char* CarlaEngineClient::getAudioPortName(const bool isInput, const uint i | |||
| CarlaStringList& portList(isInput ? pData->audioInList : pData->audioOutList); | |||
| CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr); | |||
| return portList.getAt(index, nullptr); | |||
| return portList.getAt(index); | |||
| } | |||
| const char* CarlaEngineClient::getCVPortName(const bool isInput, const uint index) const noexcept | |||
| @@ -152,7 +152,7 @@ const char* CarlaEngineClient::getCVPortName(const bool isInput, const uint inde | |||
| CarlaStringList& portList(isInput ? pData->cvInList : pData->cvOutList); | |||
| CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr); | |||
| return portList.getAt(index, nullptr); | |||
| return portList.getAt(index); | |||
| } | |||
| const char* CarlaEngineClient::getEventPortName(const bool isInput, const uint index) const noexcept | |||
| @@ -160,7 +160,7 @@ const char* CarlaEngineClient::getEventPortName(const bool isInput, const uint i | |||
| CarlaStringList& portList(isInput ? pData->eventInList : pData->eventOutList); | |||
| CARLA_SAFE_ASSERT_RETURN(index < portList.count(), nullptr); | |||
| return portList.getAt(index, nullptr); | |||
| return portList.getAt(index); | |||
| } | |||
| void CarlaEngineClient::_addAudioPortName(const bool isInput, const char* const name) | |||
| @@ -263,7 +263,6 @@ const MidiProgramData& CarlaPlugin::getMidiProgramData(const uint32_t index) con | |||
| const CustomData& CarlaPlugin::getCustomData(const uint32_t index) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->custom.count(), kCustomDataNull); | |||
| return pData->custom.getAt(index, kCustomDataFallback); | |||
| } | |||
| @@ -49,20 +49,18 @@ public: | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| fRetProgram({0, 0, nullptr}), | |||
| #endif | |||
| fPrograms() {} | |||
| fProgramCount(0), | |||
| fPrograms(nullptr) {} | |||
| ~ZynAddSubFxPrograms() noexcept | |||
| { | |||
| if (! fInitiated) | |||
| return; | |||
| for (LinkedList<const ProgramInfo*>::Itenerator it = fPrograms.begin2(); it.valid(); it.next()) | |||
| { | |||
| const ProgramInfo* const& pInfo(it.getValue(nullptr)); | |||
| delete pInfo; | |||
| } | |||
| for (uint32_t i=0; i<fProgramCount; ++i) | |||
| delete fPrograms[i]; | |||
| fPrograms.clear(); | |||
| delete[] fPrograms; | |||
| } | |||
| void initIfNeeded() | |||
| @@ -71,7 +69,8 @@ public: | |||
| return; | |||
| fInitiated = true; | |||
| fPrograms.append(new ProgramInfo(0, 0, "default", "")); | |||
| std::vector<const ProgramInfo*> programs; | |||
| programs.push_back(new ProgramInfo(0, 0, "default", "")); | |||
| Config config; | |||
| config.init(); | |||
| @@ -98,22 +97,27 @@ public: | |||
| if (instrument.name.empty() || instrument.name[0] == ' ') | |||
| continue; | |||
| fPrograms.append(new ProgramInfo(i+1, ninstrument, instrument.name.c_str(), instrument.filename.c_str())); | |||
| programs.push_back(new ProgramInfo(i+1, ninstrument, instrument.name.c_str(), instrument.filename.c_str())); | |||
| } | |||
| } | |||
| fPrograms = new const ProgramInfo*[programs.size()]; | |||
| for (const ProgramInfo* p : programs) | |||
| fPrograms[fProgramCount++] = p; | |||
| } | |||
| uint32_t getNativeMidiProgramCount() const noexcept | |||
| { | |||
| return static_cast<uint32_t>(fPrograms.count()); | |||
| return fProgramCount; | |||
| } | |||
| const NativeMidiProgram* getNativeMidiProgramInfo(const uint32_t index) const noexcept | |||
| { | |||
| if (index >= fPrograms.count()) | |||
| if (index >= fProgramCount) | |||
| return nullptr; | |||
| const ProgramInfo* const pInfo(fPrograms.getAt(index, nullptr)); | |||
| const ProgramInfo* const pInfo(fPrograms[index]); | |||
| CARLA_SAFE_ASSERT_RETURN(pInfo != nullptr, nullptr); | |||
| fRetProgram.bank = pInfo->bank; | |||
| @@ -125,9 +129,9 @@ public: | |||
| const char* getZynProgramFilename(const uint32_t bank, const uint32_t program) const noexcept | |||
| { | |||
| for (LinkedList<const ProgramInfo*>::Itenerator it = fPrograms.begin2(); it.valid(); it.next()) | |||
| for (uint32_t i=0; i<fProgramCount; ++i) | |||
| { | |||
| const ProgramInfo* const& pInfo(it.getValue(nullptr)); | |||
| const ProgramInfo* const pInfo(fPrograms[i]); | |||
| if (pInfo->bank != bank) | |||
| continue; | |||
| @@ -179,7 +183,8 @@ private: | |||
| bool fInitiated; | |||
| mutable NativeMidiProgram fRetProgram; | |||
| LinkedList<const ProgramInfo*> fPrograms; | |||
| uint32_t fProgramCount; | |||
| const ProgramInfo** fPrograms; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(ZynAddSubFxPrograms) | |||
| @@ -1753,11 +1753,15 @@ const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||
| /* extension_data */ lv2_extension_data | |||
| }; | |||
| LV2_Descriptor* const lv2Desc(new LV2_Descriptor); | |||
| LV2_Descriptor* lv2Desc; | |||
| try { | |||
| lv2Desc = new LV2_Descriptor; | |||
| } CARLA_SAFE_EXCEPTION_RETURN("new LV2_Descriptor", nullptr); | |||
| std::memcpy(lv2Desc, &lv2DescTmp, sizeof(LV2_Descriptor)); | |||
| plm.lv2Descs.append(lv2Desc); | |||
| return lv2Desc; | |||
| } | |||
| @@ -244,6 +244,23 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| const char* getAt(const std::size_t index) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, nullptr); | |||
| std::size_t i = 0; | |||
| ListHead* entry = fQueue.next; | |||
| for (; i++ != index; entry = entry->next) {} | |||
| const Data* const data(list_entry_const(entry, Data, siblings)); | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, nullptr); | |||
| return data->value; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| void remove(Itenerator& it) noexcept | |||
| { | |||
| if (const char* const string = it.getValue(nullptr)) | |||
| @@ -252,55 +252,17 @@ public: | |||
| return _add(value, false, it.fEntry->prev); | |||
| } | |||
| 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; | |||
| 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 fallback; | |||
| } | |||
| T& getAt(const std::size_t index, T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
| std::size_t i = 0; | |||
| for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
| { | |||
| if (index != i++) | |||
| continue; | |||
| return _get(entry, fallback); | |||
| } | |||
| return fallback; | |||
| } | |||
| // NOTE: do not use this function unless strictly needed. it can be very expensive if the list is big | |||
| 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 = fQueue.next; | |||
| for (ListHead *entry = fQueue.next, *entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
| { | |||
| if (index != i++) | |||
| continue; | |||
| return _get(entry, fallback); | |||
| } | |||
| for (; i++ != index; entry = entry->next) {} | |||
| return fallback; | |||
| return _get(entry, fallback); | |||
| } | |||
| T getFirst(T& fallback, const bool removeObj) noexcept | |||
| @@ -502,7 +464,7 @@ private: | |||
| return data->value; | |||
| } | |||
| const T& _get(ListHead* const entry, const T& fallback) const noexcept | |||
| const T& _get(const 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); | |||