forked from qt-creator/qt-creator
QmlDesigner: Add an reason parameter to the image cache abort callback
Sometimes we abort the request, sometimes it failed. In the first case we maybe want the cancel the imageprovider request, in the second we return an empty image. Fixes: QDS-3388 Change-Id: Iaef76aa09ac734795f86447e1a7cf6a5c7b5ae81 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
@@ -77,12 +77,19 @@ QQuickImageResponse *ItemLibraryIconImageProvider::requestImageResponse(const QS
|
|||||||
},
|
},
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
},
|
},
|
||||||
[response = QPointer<ImageRespose>(response.get())] {
|
[response = QPointer<ImageRespose>(response.get())](ImageCache::AbortReason abortReason) {
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
response,
|
response,
|
||||||
[response] {
|
[response, abortReason] {
|
||||||
if (response)
|
switch (abortReason) {
|
||||||
response->abort();
|
case ImageCache::AbortReason::Failed:
|
||||||
|
if (response)
|
||||||
|
response->abort();
|
||||||
|
break;
|
||||||
|
case ImageCache::AbortReason::Abort:
|
||||||
|
response->cancel();
|
||||||
|
break;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
});
|
});
|
||||||
|
@@ -63,7 +63,7 @@ void PreviewTooltipBackend::showTooltip()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[] {},
|
[](auto) {},
|
||||||
m_extraId,
|
m_extraId,
|
||||||
m_auxiliaryData);
|
m_auxiliaryData);
|
||||||
|
|
||||||
|
@@ -68,8 +68,8 @@ AsynchronousImageCache::~AsynchronousImageCache()
|
|||||||
void AsynchronousImageCache::request(Utils::SmallStringView name,
|
void AsynchronousImageCache::request(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
AsynchronousImageCache::RequestType requestType,
|
AsynchronousImageCache::RequestType requestType,
|
||||||
AsynchronousImageCache::CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AsynchronousImageCache::AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
ImageCache::AuxiliaryData auxiliaryData,
|
ImageCache::AuxiliaryData auxiliaryData,
|
||||||
ImageCacheStorageInterface &storage,
|
ImageCacheStorageInterface &storage,
|
||||||
ImageCacheGeneratorInterface &generator,
|
ImageCacheGeneratorInterface &generator,
|
||||||
@@ -83,7 +83,7 @@ void AsynchronousImageCache::request(Utils::SmallStringView name,
|
|||||||
|
|
||||||
if (entry.hasEntry) {
|
if (entry.hasEntry) {
|
||||||
if (entry.image.isNull())
|
if (entry.image.isNull())
|
||||||
abortCallback();
|
abortCallback(ImageCache::AbortReason::Failed);
|
||||||
else
|
else
|
||||||
captureCallback(entry.image);
|
captureCallback(entry.image);
|
||||||
} else {
|
} else {
|
||||||
@@ -109,8 +109,8 @@ void AsynchronousImageCache::wait()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AsynchronousImageCache::requestImage(Utils::PathString name,
|
void AsynchronousImageCache::requestImage(Utils::PathString name,
|
||||||
AsynchronousImageCache::CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId,
|
Utils::SmallString extraId,
|
||||||
ImageCache::AuxiliaryData auxiliaryData)
|
ImageCache::AuxiliaryData auxiliaryData)
|
||||||
{
|
{
|
||||||
@@ -124,8 +124,8 @@ void AsynchronousImageCache::requestImage(Utils::PathString name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AsynchronousImageCache::requestSmallImage(Utils::PathString name,
|
void AsynchronousImageCache::requestSmallImage(Utils::PathString name,
|
||||||
AsynchronousImageCache::CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AsynchronousImageCache::AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId,
|
Utils::SmallString extraId,
|
||||||
ImageCache::AuxiliaryData auxiliaryData)
|
ImageCache::AuxiliaryData auxiliaryData)
|
||||||
{
|
{
|
||||||
@@ -166,8 +166,8 @@ std::tuple<bool, AsynchronousImageCache::Entry> AsynchronousImageCache::getEntry
|
|||||||
|
|
||||||
void AsynchronousImageCache::addEntry(Utils::PathString &&name,
|
void AsynchronousImageCache::addEntry(Utils::PathString &&name,
|
||||||
Utils::SmallString &&extraId,
|
Utils::SmallString &&extraId,
|
||||||
AsynchronousImageCache::CaptureImageCallback &&captureCallback,
|
ImageCache::CaptureImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData,
|
ImageCache::AuxiliaryData &&auxiliaryData,
|
||||||
RequestType requestType)
|
RequestType requestType)
|
||||||
{
|
{
|
||||||
@@ -185,7 +185,7 @@ void AsynchronousImageCache::clearEntries()
|
|||||||
{
|
{
|
||||||
std::unique_lock lock{m_mutex};
|
std::unique_lock lock{m_mutex};
|
||||||
for (Entry &entry : m_entries)
|
for (Entry &entry : m_entries)
|
||||||
entry.abortCallback();
|
entry.abortCallback(ImageCache::AbortReason::Abort);
|
||||||
m_entries.clear();
|
m_entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,12 +68,10 @@ ImageCacheCollector::~ImageCacheCollector() = default;
|
|||||||
|
|
||||||
void ImageCacheCollector::start(Utils::SmallStringView name,
|
void ImageCacheCollector::start(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView state,
|
Utils::SmallStringView state,
|
||||||
const ImageCache::AuxiliaryData &auxiliaryData,
|
const ImageCache::AuxiliaryData &,
|
||||||
CaptureCallback captureCallback,
|
CaptureCallback captureCallback,
|
||||||
AbortCallback abortCallback)
|
AbortCallback abortCallback)
|
||||||
{
|
{
|
||||||
Q_UNUSED(auxiliaryData)
|
|
||||||
|
|
||||||
RewriterView rewriterView{RewriterView::Amend, nullptr};
|
RewriterView rewriterView{RewriterView::Amend, nullptr};
|
||||||
NodeInstanceView nodeInstanceView{m_connectionManager};
|
NodeInstanceView nodeInstanceView{m_connectionManager};
|
||||||
|
|
||||||
@@ -91,7 +89,7 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
|
|||||||
model->setRewriterView(&rewriterView);
|
model->setRewriterView(&rewriterView);
|
||||||
|
|
||||||
if (rewriterView.inErrorState() || !rewriterView.rootModelNode().metaInfo().isGraphicalItem()) {
|
if (rewriterView.inErrorState() || !rewriterView.rootModelNode().metaInfo().isGraphicalItem()) {
|
||||||
abortCallback();
|
abortCallback(ImageCache::AbortReason::Failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,18 +98,18 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
|
|||||||
if (stateNode.isValid())
|
if (stateNode.isValid())
|
||||||
rewriterView.setCurrentStateNode(stateNode);
|
rewriterView.setCurrentStateNode(stateNode);
|
||||||
|
|
||||||
auto callback = [captureCallback = std::move(captureCallback)](QImage &&image) {
|
auto callback = [captureCallback = std::move(captureCallback)](const QImage &image) {
|
||||||
QSize smallImageSize = image.size().scaled(QSize{96, 96}.boundedTo(image.size()),
|
QSize smallImageSize = image.size().scaled(QSize{96, 96}.boundedTo(image.size()),
|
||||||
Qt::KeepAspectRatio);
|
Qt::KeepAspectRatio);
|
||||||
QImage smallImage = image.isNull() ? QImage{} : image.scaled(smallImageSize);
|
QImage smallImage = image.isNull() ? QImage{} : image.scaled(smallImageSize);
|
||||||
|
|
||||||
captureCallback(std::move(image), std::move(smallImage));
|
captureCallback(image, smallImage);
|
||||||
};
|
};
|
||||||
|
|
||||||
m_connectionManager.setCallback(std::move(callback));
|
m_connectionManager.setCallback(std::move(callback));
|
||||||
|
|
||||||
nodeInstanceView.setTarget(m_target.data());
|
nodeInstanceView.setTarget(m_target.data());
|
||||||
nodeInstanceView.setCrashCallback(abortCallback);
|
nodeInstanceView.setCrashCallback([=] { abortCallback(ImageCache::AbortReason::Failed); });
|
||||||
model->setNodeInstanceView(&nodeInstanceView);
|
model->setNodeInstanceView(&nodeInstanceView);
|
||||||
|
|
||||||
bool capturedDataArrived = m_connectionManager.waitForCapturedData();
|
bool capturedDataArrived = m_connectionManager.waitForCapturedData();
|
||||||
@@ -123,7 +121,7 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
|
|||||||
model->setRewriterView({});
|
model->setRewriterView({});
|
||||||
|
|
||||||
if (!capturedDataArrived)
|
if (!capturedDataArrived)
|
||||||
abortCallback();
|
abortCallback(ImageCache::AbortReason::Failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<QImage, QImage> ImageCacheCollector::createImage(Utils::SmallStringView filePath,
|
std::pair<QImage, QImage> ImageCacheCollector::createImage(Utils::SmallStringView filePath,
|
||||||
|
@@ -36,8 +36,8 @@ namespace QmlDesigner {
|
|||||||
class ImageCacheCollectorInterface
|
class ImageCacheCollectorInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CaptureCallback = std::function<void(QImage &&image, QImage &&smallImage)>;
|
using CaptureCallback = ImageCache::CaptureImageWithSmallImageCallback;
|
||||||
using AbortCallback = std::function<void()>;
|
using AbortCallback = ImageCache::AbortCallback;
|
||||||
using ImagePair = std::pair<QImage, QImage>;
|
using ImagePair = std::pair<QImage, QImage>;
|
||||||
|
|
||||||
virtual void start(Utils::SmallStringView filePath,
|
virtual void start(Utils::SmallStringView filePath,
|
||||||
|
@@ -26,7 +26,7 @@ class CapturedDataCommand;
|
|||||||
class ImageCacheConnectionManager : public ConnectionManager
|
class ImageCacheConnectionManager : public ConnectionManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Callback = std::function<void(QImage &&)>;
|
using Callback = std::function<void(const QImage &)>;
|
||||||
|
|
||||||
ImageCacheConnectionManager();
|
ImageCacheConnectionManager();
|
||||||
|
|
||||||
|
@@ -140,7 +140,7 @@ void ImageCacheFontCollector::start(Utils::SmallStringView name,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
abortCallback();
|
abortCallback(ImageCache::AbortReason::Failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<QImage, QImage> ImageCacheFontCollector::createImage(
|
std::pair<QImage, QImage> ImageCacheFontCollector::createImage(
|
||||||
|
@@ -50,8 +50,8 @@ ImageCacheGenerator::~ImageCacheGenerator()
|
|||||||
void ImageCacheGenerator::generateImage(Utils::SmallStringView name,
|
void ImageCacheGenerator::generateImage(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
Sqlite::TimeStamp timeStamp,
|
Sqlite::TimeStamp timeStamp,
|
||||||
ImageCacheGeneratorInterface::CaptureCallback &&captureCallback,
|
ImageCache::CaptureImageWithSmallImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData)
|
ImageCache::AuxiliaryData &&auxiliaryData)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ void ImageCacheGenerator::clean()
|
|||||||
{
|
{
|
||||||
std::lock_guard lock{m_mutex};
|
std::lock_guard lock{m_mutex};
|
||||||
for (Task &task : m_tasks)
|
for (Task &task : m_tasks)
|
||||||
callCallbacks(task.abortCallbacks);
|
callCallbacks(task.abortCallbacks, ImageCache::AbortReason::Abort);
|
||||||
m_tasks.clear();
|
m_tasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,9 +133,9 @@ void ImageCacheGenerator::startGeneration()
|
|||||||
task.filePath,
|
task.filePath,
|
||||||
task.extraId,
|
task.extraId,
|
||||||
std::move(task.auxiliaryData),
|
std::move(task.auxiliaryData),
|
||||||
[this, task](QImage &&image, QImage &&smallImage) {
|
[this, task](const QImage &image, const QImage &smallImage) {
|
||||||
if (image.isNull())
|
if (image.isNull())
|
||||||
callCallbacks(task.abortCallbacks);
|
callCallbacks(task.abortCallbacks, ImageCache::AbortReason::Failed);
|
||||||
else
|
else
|
||||||
callCallbacks(task.captureCallbacks, image, smallImage);
|
callCallbacks(task.captureCallbacks, image, smallImage);
|
||||||
|
|
||||||
@@ -144,9 +144,10 @@ void ImageCacheGenerator::startGeneration()
|
|||||||
image,
|
image,
|
||||||
smallImage);
|
smallImage);
|
||||||
},
|
},
|
||||||
[this, task] {
|
[this, task](ImageCache::AbortReason abortReason) {
|
||||||
callCallbacks(task.abortCallbacks);
|
callCallbacks(task.abortCallbacks, abortReason);
|
||||||
m_storage.storeImage(createId(task.filePath, task.extraId), task.timeStamp, {}, {});
|
if (abortReason != ImageCache::AbortReason::Abort)
|
||||||
|
m_storage.storeImage(createId(task.filePath, task.extraId), task.timeStamp, {}, {});
|
||||||
});
|
});
|
||||||
|
|
||||||
std::lock_guard lock{m_mutex};
|
std::lock_guard lock{m_mutex};
|
||||||
|
@@ -55,8 +55,8 @@ public:
|
|||||||
void generateImage(Utils::SmallStringView filePath,
|
void generateImage(Utils::SmallStringView filePath,
|
||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
Sqlite::TimeStamp timeStamp,
|
Sqlite::TimeStamp timeStamp,
|
||||||
CaptureCallback &&captureCallback,
|
ImageCache::CaptureImageWithSmallImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData) override;
|
ImageCache::AuxiliaryData &&auxiliaryData) override;
|
||||||
void clean() override;
|
void clean() override;
|
||||||
|
|
||||||
@@ -70,8 +70,8 @@ private:
|
|||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData,
|
ImageCache::AuxiliaryData &&auxiliaryData,
|
||||||
Sqlite::TimeStamp timeStamp,
|
Sqlite::TimeStamp timeStamp,
|
||||||
CaptureCallback &&captureCallback,
|
ImageCache::CaptureImageWithSmallImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback)
|
ImageCache::AbortCallback &&abortCallback)
|
||||||
: filePath(filePath)
|
: filePath(filePath)
|
||||||
, extraId(std::move(extraId))
|
, extraId(std::move(extraId))
|
||||||
, auxiliaryData(std::move(auxiliaryData))
|
, auxiliaryData(std::move(auxiliaryData))
|
||||||
@@ -83,8 +83,8 @@ private:
|
|||||||
Utils::PathString filePath;
|
Utils::PathString filePath;
|
||||||
Utils::SmallString extraId;
|
Utils::SmallString extraId;
|
||||||
ImageCache::AuxiliaryData auxiliaryData;
|
ImageCache::AuxiliaryData auxiliaryData;
|
||||||
std::vector<CaptureCallback> captureCallbacks;
|
std::vector<ImageCache::CaptureImageWithSmallImageCallback> captureCallbacks;
|
||||||
std::vector<AbortCallback> abortCallbacks;
|
std::vector<ImageCache::AbortCallback> abortCallbacks;
|
||||||
Sqlite::TimeStamp timeStamp;
|
Sqlite::TimeStamp timeStamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -36,14 +36,11 @@ namespace QmlDesigner {
|
|||||||
class ImageCacheGeneratorInterface
|
class ImageCacheGeneratorInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CaptureCallback = std::function<void(const QImage &image, const QImage &smallImage)>;
|
|
||||||
using AbortCallback = std::function<void()>;
|
|
||||||
|
|
||||||
virtual void generateImage(Utils::SmallStringView name,
|
virtual void generateImage(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
Sqlite::TimeStamp timeStamp,
|
Sqlite::TimeStamp timeStamp,
|
||||||
CaptureCallback &&captureCallback,
|
ImageCache::CaptureImageWithSmallImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData)
|
ImageCache::AuxiliaryData &&auxiliaryData)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
@@ -43,8 +43,6 @@ class ImageCacheCollectorInterface;
|
|||||||
class AsynchronousImageCache final : public AsynchronousImageCacheInterface
|
class AsynchronousImageCache final : public AsynchronousImageCacheInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CaptureImageCallback = std::function<void(const QImage &)>;
|
|
||||||
using AbortCallback = std::function<void()>;
|
|
||||||
|
|
||||||
~AsynchronousImageCache();
|
~AsynchronousImageCache();
|
||||||
|
|
||||||
@@ -53,13 +51,13 @@ public:
|
|||||||
TimeStampProviderInterface &timeStampProvider);
|
TimeStampProviderInterface &timeStampProvider);
|
||||||
|
|
||||||
void requestImage(Utils::PathString name,
|
void requestImage(Utils::PathString name,
|
||||||
CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId = {},
|
Utils::SmallString extraId = {},
|
||||||
ImageCache::AuxiliaryData auxiliaryData = {}) override;
|
ImageCache::AuxiliaryData auxiliaryData = {}) override;
|
||||||
void requestSmallImage(Utils::PathString name,
|
void requestSmallImage(Utils::PathString name,
|
||||||
CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId = {},
|
Utils::SmallString extraId = {},
|
||||||
ImageCache::AuxiliaryData auxiliaryData = {}) override;
|
ImageCache::AuxiliaryData auxiliaryData = {}) override;
|
||||||
|
|
||||||
@@ -73,8 +71,8 @@ private:
|
|||||||
Entry() = default;
|
Entry() = default;
|
||||||
Entry(Utils::PathString name,
|
Entry(Utils::PathString name,
|
||||||
Utils::SmallString extraId,
|
Utils::SmallString extraId,
|
||||||
CaptureImageCallback &&captureCallback,
|
ImageCache::CaptureImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData,
|
ImageCache::AuxiliaryData &&auxiliaryData,
|
||||||
RequestType requestType)
|
RequestType requestType)
|
||||||
: name{std::move(name)}
|
: name{std::move(name)}
|
||||||
@@ -87,8 +85,8 @@ private:
|
|||||||
|
|
||||||
Utils::PathString name;
|
Utils::PathString name;
|
||||||
Utils::SmallString extraId;
|
Utils::SmallString extraId;
|
||||||
CaptureImageCallback captureCallback;
|
ImageCache::CaptureImageCallback captureCallback;
|
||||||
AbortCallback abortCallback;
|
ImageCache::AbortCallback abortCallback;
|
||||||
ImageCache::AuxiliaryData auxiliaryData;
|
ImageCache::AuxiliaryData auxiliaryData;
|
||||||
RequestType requestType = RequestType::Image;
|
RequestType requestType = RequestType::Image;
|
||||||
};
|
};
|
||||||
@@ -96,8 +94,8 @@ private:
|
|||||||
std::tuple<bool, Entry> getEntry();
|
std::tuple<bool, Entry> getEntry();
|
||||||
void addEntry(Utils::PathString &&name,
|
void addEntry(Utils::PathString &&name,
|
||||||
Utils::SmallString &&extraId,
|
Utils::SmallString &&extraId,
|
||||||
CaptureImageCallback &&captureCallback,
|
ImageCache::CaptureImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
ImageCache::AbortCallback &&abortCallback,
|
||||||
ImageCache::AuxiliaryData &&auxiliaryData,
|
ImageCache::AuxiliaryData &&auxiliaryData,
|
||||||
RequestType requestType);
|
RequestType requestType);
|
||||||
void clearEntries();
|
void clearEntries();
|
||||||
@@ -107,8 +105,8 @@ private:
|
|||||||
static void request(Utils::SmallStringView name,
|
static void request(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView extraId,
|
Utils::SmallStringView extraId,
|
||||||
AsynchronousImageCache::RequestType requestType,
|
AsynchronousImageCache::RequestType requestType,
|
||||||
AsynchronousImageCache::CaptureImageCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AsynchronousImageCache::AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
ImageCache::AuxiliaryData auxiliaryData,
|
ImageCache::AuxiliaryData auxiliaryData,
|
||||||
ImageCacheStorageInterface &storage,
|
ImageCacheStorageInterface &storage,
|
||||||
ImageCacheGeneratorInterface &generator,
|
ImageCacheGeneratorInterface &generator,
|
||||||
|
@@ -36,18 +36,15 @@ namespace QmlDesigner {
|
|||||||
class AsynchronousImageCacheInterface
|
class AsynchronousImageCacheInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using CaptureCallback = std::function<void(const QImage &)>;
|
|
||||||
using AbortCallback = std::function<void()>;
|
|
||||||
|
|
||||||
virtual void requestImage(Utils::PathString name,
|
virtual void requestImage(Utils::PathString name,
|
||||||
CaptureCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId = {},
|
Utils::SmallString extraId = {},
|
||||||
ImageCache::AuxiliaryData auxiliaryData = {})
|
ImageCache::AuxiliaryData auxiliaryData = {})
|
||||||
= 0;
|
= 0;
|
||||||
virtual void requestSmallImage(Utils::PathString name,
|
virtual void requestSmallImage(Utils::PathString name,
|
||||||
CaptureCallback captureCallback,
|
ImageCache::CaptureImageCallback captureCallback,
|
||||||
AbortCallback abortCallback,
|
ImageCache::AbortCallback abortCallback,
|
||||||
Utils::SmallString extraId = {},
|
Utils::SmallString extraId = {},
|
||||||
ImageCache::AuxiliaryData auxiliaryData = {})
|
ImageCache::AuxiliaryData auxiliaryData = {})
|
||||||
= 0;
|
= 0;
|
||||||
|
@@ -28,9 +28,12 @@
|
|||||||
#include <utils/span.h>
|
#include <utils/span.h>
|
||||||
#include <utils/variant.h>
|
#include <utils/variant.h>
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
namespace ImageCache {
|
namespace ImageCache {
|
||||||
@@ -56,6 +59,11 @@ public:
|
|||||||
|
|
||||||
using AuxiliaryData = Utils::variant<NullAuxiliaryData, FontCollectorSizeAuxiliaryData, FontCollectorSizesAuxiliaryData>;
|
using AuxiliaryData = Utils::variant<NullAuxiliaryData, FontCollectorSizeAuxiliaryData, FontCollectorSizesAuxiliaryData>;
|
||||||
|
|
||||||
|
enum class AbortReason : char { Abort, Failed };
|
||||||
|
|
||||||
|
using CaptureImageCallback = std::function<void(const QImage &)>;
|
||||||
|
using CaptureImageWithSmallImageCallback = std::function<void(const QImage &image, const QImage &smallImage)>;
|
||||||
|
using AbortCallback = std::function<void(ImageCache::AbortReason)>;
|
||||||
} // namespace ImageCache
|
} // namespace ImageCache
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -39,7 +39,7 @@ class AsynchronousImageCache : public testing::Test
|
|||||||
protected:
|
protected:
|
||||||
Notification notification;
|
Notification notification;
|
||||||
Notification waitInThread;
|
Notification waitInThread;
|
||||||
NiceMock<MockFunction<void()>> mockAbortCallback;
|
NiceMock<MockFunction<void(QmlDesigner::ImageCache::AbortReason)>> mockAbortCallback;
|
||||||
NiceMock<MockFunction<void(const QImage &image)>> mockCaptureCallback;
|
NiceMock<MockFunction<void(const QImage &image)>> mockCaptureCallback;
|
||||||
NiceMock<MockImageCacheStorage> mockStorage;
|
NiceMock<MockImageCacheStorage> mockStorage;
|
||||||
NiceMock<MockImageCacheGenerator> mockGenerator;
|
NiceMock<MockImageCacheGenerator> mockGenerator;
|
||||||
@@ -99,7 +99,8 @@ TEST_F(AsynchronousImageCache, RequestImageCallsAbortCallbackWithoutImage)
|
|||||||
ON_CALL(mockStorage, fetchImage(Eq("/path/to/Component.qml"), _))
|
ON_CALL(mockStorage, fetchImage(Eq("/path/to/Component.qml"), _))
|
||||||
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{QImage{}, true}));
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{QImage{}, true}));
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call()).WillRepeatedly([&] { notification.notify(); });
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
||||||
|
.WillRepeatedly([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
cache.requestImage("/path/to/Component.qml",
|
cache.requestImage("/path/to/Component.qml",
|
||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
@@ -142,11 +143,11 @@ TEST_F(AsynchronousImageCache, RequestImageCallsAbortCallbackFromGenerator)
|
|||||||
{
|
{
|
||||||
ON_CALL(mockGenerator, generateImage(Eq("/path/to/Component.qml"), _, _, _, _, _))
|
ON_CALL(mockGenerator, generateImage(Eq("/path/to/Component.qml"), _, _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto &&, auto &&abortCallback, auto) {
|
.WillByDefault([&](auto, auto, auto, auto &&, auto &&abortCallback, auto) {
|
||||||
abortCallback();
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
notification.notify();
|
notification.notify();
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call());
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)));
|
||||||
|
|
||||||
cache.requestImage("/path/to/Component.qml",
|
cache.requestImage("/path/to/Component.qml",
|
||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
@@ -204,7 +205,8 @@ TEST_F(AsynchronousImageCache, RequestSmallImageCallsAbortCallbackWithoutSmallIm
|
|||||||
ON_CALL(mockStorage, fetchSmallImage(Eq("/path/to/Component.qml"), _))
|
ON_CALL(mockStorage, fetchSmallImage(Eq("/path/to/Component.qml"), _))
|
||||||
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{QImage{}, true}));
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::ImageEntry{QImage{}, true}));
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call()).WillRepeatedly([&] { notification.notify(); });
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
||||||
|
.WillRepeatedly([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
cache.requestSmallImage("/path/to/Component.qml",
|
cache.requestSmallImage("/path/to/Component.qml",
|
||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
@@ -247,11 +249,11 @@ TEST_F(AsynchronousImageCache, RequestSmallImageCallsAbortCallbackFromGenerator)
|
|||||||
{
|
{
|
||||||
ON_CALL(mockGenerator, generateImage(Eq("/path/to/Component.qml"), _, _, _, _, _))
|
ON_CALL(mockGenerator, generateImage(Eq("/path/to/Component.qml"), _, _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto &&, auto &&abortCallback, auto) {
|
.WillByDefault([&](auto, auto, auto, auto &&, auto &&abortCallback, auto) {
|
||||||
abortCallback();
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
notification.notify();
|
notification.notify();
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call());
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)));
|
||||||
|
|
||||||
cache.requestSmallImage("/path/to/Component.qml",
|
cache.requestSmallImage("/path/to/Component.qml",
|
||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
@@ -292,7 +294,8 @@ TEST_F(AsynchronousImageCache, CleanCallsAbort)
|
|||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
mockAbortCallback.AsStdFunction());
|
mockAbortCallback.AsStdFunction());
|
||||||
|
|
||||||
EXPECT_CALL(mockAbortCallback, Call()).Times(AtLeast(2));
|
EXPECT_CALL(mockAbortCallback, Call(Eq(QmlDesigner::ImageCache::AbortReason::Abort)))
|
||||||
|
.Times(AtLeast(2));
|
||||||
|
|
||||||
cache.requestSmallImage("/path/to/Component3.qml",
|
cache.requestSmallImage("/path/to/Component3.qml",
|
||||||
mockCaptureCallback.AsStdFunction(),
|
mockCaptureCallback.AsStdFunction(),
|
||||||
|
@@ -56,7 +56,7 @@ protected:
|
|||||||
QImage image1{10, 10, QImage::Format_ARGB32};
|
QImage image1{10, 10, QImage::Format_ARGB32};
|
||||||
QImage smallImage1{1, 1, QImage::Format_ARGB32};
|
QImage smallImage1{1, 1, QImage::Format_ARGB32};
|
||||||
NiceMock<MockFunction<void(const QImage &, const QImage &)>> imageCallbackMock;
|
NiceMock<MockFunction<void(const QImage &, const QImage &)>> imageCallbackMock;
|
||||||
NiceMock<MockFunction<void()>> abortCallbackMock;
|
NiceMock<MockFunction<void(QmlDesigner::ImageCache::AbortReason)>> abortCallbackMock;
|
||||||
NiceMock<ImageCacheCollectorMock> collectorMock;
|
NiceMock<ImageCacheCollectorMock> collectorMock;
|
||||||
NiceMock<MockImageCacheStorage> storageMock;
|
NiceMock<MockImageCacheStorage> storageMock;
|
||||||
QmlDesigner::ImageCacheGenerator generator{collectorMock, storageMock};
|
QmlDesigner::ImageCacheGenerator generator{collectorMock, storageMock};
|
||||||
@@ -196,12 +196,15 @@ TEST_F(ImageCacheGenerator, AbortCallback)
|
|||||||
captureCallback(QImage{image1}, QImage{smallImage1});
|
captureCallback(QImage{image1}, QImage{smallImage1});
|
||||||
});
|
});
|
||||||
ON_CALL(collectorMock, start(Eq("name2"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("name2"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) { abortCallback(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) {
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(imageCallbackMock, Call(_, _)).WillOnce([&](const QImage &, const QImage &) {
|
EXPECT_CALL(imageCallbackMock, Call(_, _)).WillOnce([&](const QImage &, const QImage &) {
|
||||||
notification.notify();
|
notification.notify();
|
||||||
});
|
});
|
||||||
EXPECT_CALL(abortCallbackMock, Call()).WillOnce([&]() { notification.notify(); });
|
EXPECT_CALL(abortCallbackMock, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
||||||
|
.WillOnce([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
generator.generateImage(
|
generator.generateImage(
|
||||||
"name", {}, {}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
"name", {}, {}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
||||||
@@ -210,10 +213,29 @@ TEST_F(ImageCacheGenerator, AbortCallback)
|
|||||||
notification.wait(2);
|
notification.wait(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ImageCacheGenerator, StoreNullImageForAbortCallback)
|
TEST_F(ImageCacheGenerator, StoreNullImageForAbortCallbackAbort)
|
||||||
|
{
|
||||||
|
ON_CALL(collectorMock, start(Eq("name"), _, _, _, _))
|
||||||
|
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) {
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Abort);
|
||||||
|
});
|
||||||
|
ON_CALL(collectorMock, start(Eq("dummyNotify"), _, _, _, _))
|
||||||
|
.WillByDefault([&](auto, auto, auto, auto, auto) { notification.notify(); });
|
||||||
|
|
||||||
|
EXPECT_CALL(storageMock, storeImage(Eq("name"), _, _, _)).Times(0);
|
||||||
|
|
||||||
|
generator.generateImage(
|
||||||
|
"name", {}, {11}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
||||||
|
generator.generateImage("dummyNotify", {}, {}, {}, {}, {});
|
||||||
|
notification.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheGenerator, DontStoreNullImageForAbortCallbackFailed)
|
||||||
{
|
{
|
||||||
ON_CALL(collectorMock, start(_, _, _, _, _))
|
ON_CALL(collectorMock, start(_, _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) { abortCallback(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) {
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(storageMock,
|
EXPECT_CALL(storageMock,
|
||||||
storeImage(Eq("name"), Eq(Sqlite::TimeStamp{11}), Eq(QImage{}), Eq(QImage{})))
|
storeImage(Eq("name"), Eq(Sqlite::TimeStamp{11}), Eq(QImage{}), Eq(QImage{})))
|
||||||
@@ -231,7 +253,8 @@ TEST_F(ImageCacheGenerator, AbortForEmptyImage)
|
|||||||
captureCallback(QImage{}, QImage{});
|
captureCallback(QImage{}, QImage{});
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_CALL(abortCallbackMock, Call()).WillOnce([&]() { notification.notify(); });
|
EXPECT_CALL(abortCallbackMock, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)))
|
||||||
|
.WillOnce([&](auto) { notification.notify(); });
|
||||||
|
|
||||||
generator.generateImage(
|
generator.generateImage(
|
||||||
"name", {}, {}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
"name", {}, {}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
||||||
@@ -264,7 +287,8 @@ TEST_F(ImageCacheGenerator, CleanIsCallingAbortCallback)
|
|||||||
generator.generateImage(
|
generator.generateImage(
|
||||||
"name2", {}, {11}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
"name2", {}, {11}, imageCallbackMock.AsStdFunction(), abortCallbackMock.AsStdFunction(), {});
|
||||||
|
|
||||||
EXPECT_CALL(abortCallbackMock, Call()).Times(AtLeast(1));
|
EXPECT_CALL(abortCallbackMock, Call(Eq(QmlDesigner::ImageCache::AbortReason::Abort)))
|
||||||
|
.Times(AtLeast(1));
|
||||||
|
|
||||||
generator.clean();
|
generator.clean();
|
||||||
waitInThread.notify();
|
waitInThread.notify();
|
||||||
@@ -401,9 +425,11 @@ TEST_F(ImageCacheGenerator, UseLastTimeStampIfTasksAreMerged)
|
|||||||
ON_CALL(collectorMock, start(Eq("notificationDummy"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("notificationDummy"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto) { notification.notify(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto) { notification.notify(); });
|
||||||
ON_CALL(collectorMock, start(Eq("name"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("name"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) { abortCallback(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) {
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(storageMock, storeImage(Eq("name"), _, _, _));
|
EXPECT_CALL(storageMock, storeImage(Eq("name"), Eq(Sqlite::TimeStamp{4}), _, _));
|
||||||
|
|
||||||
generator.generateImage("waitDummy", {}, {}, {}, {}, {});
|
generator.generateImage("waitDummy", {}, {}, {}, {}, {});
|
||||||
generator.generateImage("name", {}, {3}, {}, abortCallbackMock.AsStdFunction(), {});
|
generator.generateImage("name", {}, {3}, {}, abortCallbackMock.AsStdFunction(), {});
|
||||||
@@ -438,16 +464,18 @@ TEST_F(ImageCacheGenerator, MergeCaptureCallbackIfTasksAreMerged)
|
|||||||
|
|
||||||
TEST_F(ImageCacheGenerator, MergeAbortCallbackIfTasksAreMerged)
|
TEST_F(ImageCacheGenerator, MergeAbortCallbackIfTasksAreMerged)
|
||||||
{
|
{
|
||||||
NiceMock<MockFunction<void()>> newerAbortCallbackMock;
|
NiceMock<MockFunction<void(QmlDesigner::ImageCache::AbortReason)>> newerAbortCallbackMock;
|
||||||
ON_CALL(collectorMock, start(Eq("waitDummy"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("waitDummy"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto) { waitInThread.wait(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto) { waitInThread.wait(); });
|
||||||
ON_CALL(collectorMock, start(Eq("notificationDummy"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("notificationDummy"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto) { notification.notify(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto) { notification.notify(); });
|
||||||
ON_CALL(collectorMock, start(Eq("name"), _, _, _, _))
|
ON_CALL(collectorMock, start(Eq("name"), _, _, _, _))
|
||||||
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) { abortCallback(); });
|
.WillByDefault([&](auto, auto, auto, auto, auto abortCallback) {
|
||||||
|
abortCallback(QmlDesigner::ImageCache::AbortReason::Failed);
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(abortCallbackMock, Call());
|
EXPECT_CALL(abortCallbackMock, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)));
|
||||||
EXPECT_CALL(newerAbortCallbackMock, Call());
|
EXPECT_CALL(newerAbortCallbackMock, Call(Eq(QmlDesigner::ImageCache::AbortReason::Failed)));
|
||||||
|
|
||||||
generator.generateImage("waitDummy", {}, {}, {}, {}, {});
|
generator.generateImage("waitDummy", {}, {}, {}, {}, {});
|
||||||
generator.generateImage("name", {}, {}, {}, abortCallbackMock.AsStdFunction(), {});
|
generator.generateImage("name", {}, {}, {}, abortCallbackMock.AsStdFunction(), {});
|
||||||
|
@@ -37,8 +37,8 @@ public:
|
|||||||
(Utils::SmallStringView name,
|
(Utils::SmallStringView name,
|
||||||
Utils::SmallStringView state,
|
Utils::SmallStringView state,
|
||||||
Sqlite::TimeStamp timeStamp,
|
Sqlite::TimeStamp timeStamp,
|
||||||
CaptureCallback &&captureCallback,
|
QmlDesigner::ImageCache::CaptureImageWithSmallImageCallback &&captureCallback,
|
||||||
AbortCallback &&abortCallback,
|
QmlDesigner::ImageCache::AbortCallback &&abortCallback,
|
||||||
QmlDesigner::ImageCache::AuxiliaryData &&auxiliaryData),
|
QmlDesigner::ImageCache::AuxiliaryData &&auxiliaryData),
|
||||||
(override));
|
(override));
|
||||||
MOCK_METHOD(void, clean, (), (override));
|
MOCK_METHOD(void, clean, (), (override));
|
||||||
|
Reference in New Issue
Block a user