File indexing completed on 2024-05-12 15:59:48

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KISREQUIREDRESOURCESOPERATORS_H
0007 #define KISREQUIREDRESOURCESOPERATORS_H
0008 
0009 #include "kritaresources_export.h"
0010 
0011 #include <KisResourcesInterface.h>
0012 #include <KoResourceLoadResult.h>
0013 #include "kis_assert.h"
0014 
0015 #include "kis_pointer_utils.h"
0016 
0017 namespace KisRequiredResourcesOperators
0018 {
0019 
0020 namespace detail {
0021 bool KRITARESOURCES_EXPORT isLocalResourcesStorage(KisResourcesInterfaceSP resourcesInterface);
0022 void KRITARESOURCES_EXPORT assertInGuiThread();
0023 KisResourcesInterfaceSP KRITARESOURCES_EXPORT createLocalResourcesStorage(const QList<KoResourceSP> &resources);
0024 void KRITARESOURCES_EXPORT addResourceOrWarnIfNotLoaded(KoResourceLoadResult loadedResource, QList<KoResourceSP> *resources, KisResourcesInterfaceSP resourcesInterface);
0025 }
0026 
0027 
0028 /**
0029  * @return true if the configuration has all the necessary resources in
0030  * local storage. It mean it can be used in a threaded environment.
0031  *
0032  * @see createLocalResourcesSnapshot()
0033  */
0034 template <typename T>
0035 bool hasLocalResourcesSnapshot(const T *object)
0036 {
0037     return detail::isLocalResourcesStorage(object->resourcesInterface());
0038 }
0039 
0040 /**
0041  * Loads all the required resources either from the current resource interface
0042  * or from the embedded data. The object first tries to fetch the required
0043  * resource from the current source, and only if it fails, tries to load
0044  * it from the embedded data.
0045  *
0046  * @param globalResourcesInterface if \p globalResourcesInterface is not null,
0047  * the resources are fetched from there, not from the internally stored resources
0048  * interface
0049  */
0050 template <typename T>
0051 void createLocalResourcesSnapshot(T *object, KisResourcesInterfaceSP globalResourcesInterface = nullptr)
0052 {
0053     detail::assertInGuiThread();
0054 
0055     KisResourcesInterfaceSP effectiveResourcesInterface =
0056         globalResourcesInterface ?
0057             globalResourcesInterface :
0058             object->resourcesInterface();
0059 
0060     QList<KoResourceLoadResult> loadedResources =
0061         object->requiredResources(effectiveResourcesInterface);
0062 
0063     QList<KoResourceSP> resources;
0064 
0065     Q_FOREACH(const KoResourceLoadResult &loadedResource, loadedResources) {
0066         detail::addResourceOrWarnIfNotLoaded(loadedResource, &resources, effectiveResourcesInterface);
0067     }
0068 
0069     object->setResourcesInterface(detail::createLocalResourcesStorage(resources));
0070 }
0071 
0072 /**
0073  * @brief creates an exact copy of the object and loads all the linked
0074  *        resources into the local storage.
0075  * @param globalResourcesInterface is an optional override for the
0076  *        resources interface used for fetching linked resources. If
0077  *        \p globalResourcesInterface is null, then object->resourcesInterface()
0078  *        is used.
0079  *
0080  * If a filter configuration object already has a resources snapshot, then
0081  * the function just clones the object without reloading anything.
0082  */
0083 template <typename TypeSP, typename T = typename KisSharedPointerTraits<TypeSP>::ValueType>
0084 TypeSP cloneWithResourcesSnapshot(const T* object,
0085                                   KisResourcesInterfaceSP globalResourcesInterface = nullptr)
0086 {
0087     auto clonedStorage = object->clone();
0088     TypeSP cloned = KisSharedPointerTraits<TypeSP>::template dynamicCastSP<T>(clonedStorage);
0089 
0090     if (!hasLocalResourcesSnapshot(cloned.data())) {
0091         createLocalResourcesSnapshot(cloned.data(), globalResourcesInterface);
0092         KIS_SAFE_ASSERT_RECOVER_NOOP(hasLocalResourcesSnapshot(cloned.data()));
0093     }
0094 
0095     return cloned;
0096 }
0097 
0098 }
0099 
0100 #endif // KISREQUIREDRESOURCESOPERATORS_H