/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #pragma once #include "aggregation_global.h" #include #include #include #include #include namespace Aggregation { class AGGREGATION_EXPORT Aggregate : public QObject { Q_OBJECT public: Aggregate(QObject *parent = nullptr); ~Aggregate() override; void add(QObject *component); void remove(QObject *component); template T *component() { QReadLocker locker(&lock()); foreach (QObject *component, m_components) { if (T *result = qobject_cast(component)) return result; } return nullptr; } template QList components() { QReadLocker locker(&lock()); QList results; foreach (QObject *component, m_components) { if (T *result = qobject_cast(component)) { results << result; } } return results; } static Aggregate *parentAggregate(QObject *obj); static QReadWriteLock &lock(); signals: void changed(); private: void deleteSelf(QObject *obj); static QHash &aggregateMap(); QList m_components; }; // get a component via global template function template T *query(Aggregate *obj) { if (!obj) return nullptr; return obj->template component(); } template T *query(QObject *obj) { if (!obj) return nullptr; T *result = qobject_cast(obj); if (!result) { QReadLocker locker(&Aggregate::lock()); Aggregate *parentAggregation = Aggregate::parentAggregate(obj); result = (parentAggregation ? query(parentAggregation) : nullptr); } return result; } // get all components of a specific type via template function template QList query_all(Aggregate *obj) { if (!obj) return QList(); return obj->template components(); } template QList query_all(QObject *obj) { if (!obj) return QList(); QReadLocker locker(&Aggregate::lock()); Aggregate *parentAggregation = Aggregate::parentAggregate(obj); QList results; if (parentAggregation) results = query_all(parentAggregation); else if (T *result = qobject_cast(obj)) results.append(result); return results; } } // namespace Aggregation