diff --git a/rtengine/utils.h b/rtengine/utils.h index 5dec93f51..f57163d1e 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -18,6 +18,7 @@ */ #pragma once +#include #include #include @@ -26,6 +27,37 @@ namespace rtengine { +/** + * A function object that supplies a value and returns the same value for + * subsequent calls. + */ +template +struct MemoizingSupplier { + using Supplier = std::function; + + /** + * @param supplier The delegate supplier. + */ + explicit MemoizingSupplier(const Supplier &supplier) : + supplier(supplier) + { + } + + T operator()() const + { + if (!is_cached) { + value = supplier(); + is_cached = true; + } + return value; + } + +private: + const Supplier supplier; + mutable T value; + mutable bool is_cached{false}; +}; + // Update a point of a Cairo::Surface by accessing the raw data void poke255_uc(unsigned char*& dest, unsigned char r, unsigned char g, unsigned char b); // Update a point of a Cairo::Surface by accessing the raw data diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 26c96546e..b7f634b0e 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -37,6 +37,7 @@ #include "rtengine/metadata.h" #include "rtengine/profilestore.h" #include "rtengine/settings.h" +#include "rtengine/utils.h" #include "guiutils.h" #include "batchqueue.h" #include "extprog.h" @@ -1418,10 +1419,9 @@ void Thumbnail::updateProcParamsProperties(bool forceUpdate) pparamsValid = true; } - const auto getXmpSidecar = [this]() { - static auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname); - return xmp; - }; + const rtengine::MemoizingSupplier getXmpSidecar([this]() { + return rtengine::Exiv2Metadata::getXmpSidecar(fname); + }); // save procparams rank and color also when options.thumbnailRankColorMode == Options::ThumbnailPropertyMode::XMP // so they'll be kept in sync