// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #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()); for (QObject *component : std::as_const(m_components)) { if (T *result = qobject_cast(component)) return result; } return nullptr; } template QList components() { QReadLocker locker(&lock()); QList results; for (QObject *component : std::as_const(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 {}; return obj->template components(); } template QList query_all(QObject *obj) { if (!obj) return {}; 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