/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020 Edouard Griffiths, F4EXB // // Copyright (C) 2021 Jon Beniston, M7RCE // // Copyright (C) 2022 Jiří Pinkava // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #ifndef SDRBASE_PIPES_ELEMNTPIPESREGISTRATION_H_ #define SDRBASE_PIPES_ELEMNTPIPESREGISTRATION_H_ #include #include #include #include #include "elementpipescommon.h" template class ElementPipesRegistrations { public: ElementPipesRegistrations() : m_typeCount(0), m_mutex(QRecursiveMutex::Recursive) {} ~ElementPipesRegistrations() { typename QMap, QList>::iterator mit = m_elements.begin(); for (; mit != m_elements.end(); ++mit) { typename QList::iterator elIt = mit->begin(); for (; elIt != mit->end(); ++elIt) { delete *elIt; } } } Element *registerProducerToConsumer(const Producer *producer, Consumer *consumer, const QString& type) { int typeId; QMutexLocker mlock(&m_mutex); if (m_typeIds.contains(type)) { typeId = m_typeIds.value(type); } else { typeId = m_typeCount++; m_typeIds.insert(type, typeId); } const typename ElementPipesCommon::RegistrationKey regKey = ElementPipesCommon::RegistrationKey{producer, typeId}; Element *element; if (m_consumers[regKey].contains(consumer)) { int i = m_consumers[regKey].indexOf(consumer); element = m_elements[regKey][i]; } else { element = new Element(); m_elements[regKey].append(element); m_consumers[regKey].append(consumer); } return element; } Element *unregisterProducerToConsumer(const Producer *producer, Consumer *consumer, const QString& type) { Element *element = nullptr; if (m_typeIds.contains(type)) { int typeId = m_typeIds.value(type); const typename ElementPipesCommon::RegistrationKey regKey = ElementPipesCommon::RegistrationKey{producer, typeId}; if (m_consumers.contains(regKey) && m_consumers[regKey].contains(consumer)) { QMutexLocker mlock(&m_mutex); int i = m_consumers[regKey].indexOf(consumer); m_consumers[regKey].removeAt(i); element = m_elements[regKey][i]; // delete element; // will be deferred to GC m_elements[regKey].removeAt(i); } } return element; } QList* getElements(const Producer *producer, const QString& type) { if (!m_typeIds.contains(type)) { return nullptr; } QMutexLocker mlock(&m_mutex); const typename ElementPipesCommon::RegistrationKey regKey = ElementPipesCommon::RegistrationKey{producer, m_typeIds.value(type)}; if (m_elements.contains(regKey)) { return &m_elements[regKey]; } else { return nullptr; } } QMap, QList> *getElements() { return &m_elements; } QMap, QList> *getConsumers() { return &m_consumers; } QRecursiveMutex *getMutex() { return &m_mutex; } private: QHash m_typeIds; int m_typeCount; QMap, QList> m_elements; QMap, QList> m_consumers; QRecursiveMutex m_mutex; }; #endif // SDRBASE_PIPES_ELEMNTPIPESREGISTRATION_H_