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