forked from qt-creator/qt-creator
QmlDesigner: Add waitForFinished to ImageCache
Task-number: QDS-2998 Change-Id: I5ffb63b7345a17ccb499db876bb4dbb0a946ed85 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -60,10 +60,7 @@ ImageCache::ImageCache(ImageCacheStorageInterface &storage,
|
|||||||
ImageCache::~ImageCache()
|
ImageCache::~ImageCache()
|
||||||
{
|
{
|
||||||
clean();
|
clean();
|
||||||
stopThread();
|
wait();
|
||||||
m_condition.notify_all();
|
|
||||||
if (m_backgroundThread.joinable())
|
|
||||||
m_backgroundThread.join();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageCache::request(Utils::SmallStringView name,
|
void ImageCache::request(Utils::SmallStringView name,
|
||||||
@@ -88,6 +85,14 @@ void ImageCache::request(Utils::SmallStringView name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageCache::wait()
|
||||||
|
{
|
||||||
|
stopThread();
|
||||||
|
m_condition.notify_all();
|
||||||
|
if (m_backgroundThread.joinable())
|
||||||
|
m_backgroundThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
void ImageCache::requestImage(Utils::PathString name,
|
void ImageCache::requestImage(Utils::PathString name,
|
||||||
ImageCache::CaptureCallback captureCallback,
|
ImageCache::CaptureCallback captureCallback,
|
||||||
AbortCallback abortCallback)
|
AbortCallback abortCallback)
|
||||||
@@ -110,6 +115,13 @@ void ImageCache::clean()
|
|||||||
m_generator.clean();
|
m_generator.clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageCache::waitForFinished()
|
||||||
|
{
|
||||||
|
wait();
|
||||||
|
|
||||||
|
m_generator.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<bool, ImageCache::Entry> ImageCache::getEntry()
|
std::tuple<bool, ImageCache::Entry> ImageCache::getEntry()
|
||||||
{
|
{
|
||||||
std::unique_lock lock{m_mutex};
|
std::unique_lock lock{m_mutex};
|
||||||
@@ -160,7 +172,7 @@ void ImageCache::stopThread()
|
|||||||
bool ImageCache::isRunning()
|
bool ImageCache::isRunning()
|
||||||
{
|
{
|
||||||
std::unique_lock lock{m_mutex};
|
std::unique_lock lock{m_mutex};
|
||||||
return !m_finishing;
|
return !m_finishing || m_entries.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -44,11 +44,7 @@ ImageCacheGenerator::ImageCacheGenerator(ImageCacheCollectorInterface &collector
|
|||||||
ImageCacheGenerator::~ImageCacheGenerator()
|
ImageCacheGenerator::~ImageCacheGenerator()
|
||||||
{
|
{
|
||||||
clean();
|
clean();
|
||||||
stopThread();
|
waitForFinished();
|
||||||
m_condition.notify_all();
|
|
||||||
|
|
||||||
if (m_backgroundThread)
|
|
||||||
m_backgroundThread->wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageCacheGenerator::generateImage(Utils::SmallStringView name,
|
void ImageCacheGenerator::generateImage(Utils::SmallStringView name,
|
||||||
@@ -72,6 +68,15 @@ void ImageCacheGenerator::clean()
|
|||||||
m_tasks.clear();
|
m_tasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageCacheGenerator::waitForFinished()
|
||||||
|
{
|
||||||
|
stopThread();
|
||||||
|
m_condition.notify_all();
|
||||||
|
|
||||||
|
if (m_backgroundThread)
|
||||||
|
m_backgroundThread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
void ImageCacheGenerator::startGeneration()
|
void ImageCacheGenerator::startGeneration()
|
||||||
{
|
{
|
||||||
while (isRunning()) {
|
while (isRunning()) {
|
||||||
@@ -82,7 +87,7 @@ void ImageCacheGenerator::startGeneration()
|
|||||||
{
|
{
|
||||||
std::lock_guard lock{m_mutex};
|
std::lock_guard lock{m_mutex};
|
||||||
|
|
||||||
if (m_finishing) {
|
if (m_finishing && m_tasks.empty()) {
|
||||||
m_storage.walCheckpointFull();
|
m_storage.walCheckpointFull();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -129,7 +134,7 @@ void ImageCacheGenerator::stopThread()
|
|||||||
bool ImageCacheGenerator::isRunning()
|
bool ImageCacheGenerator::isRunning()
|
||||||
{
|
{
|
||||||
std::unique_lock lock{m_mutex};
|
std::unique_lock lock{m_mutex};
|
||||||
return !m_finishing;
|
return !m_finishing || m_tasks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public:
|
|||||||
AbortCallback &&abortCallback) override;
|
AbortCallback &&abortCallback) override;
|
||||||
void clean() override;
|
void clean() override;
|
||||||
|
|
||||||
|
void waitForFinished() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Task
|
struct Task
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
virtual void clean() = 0;
|
virtual void clean() = 0;
|
||||||
|
virtual void waitForFinished() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~ImageCacheGeneratorInterface() = default;
|
~ImageCacheGeneratorInterface() = default;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ public:
|
|||||||
AbortCallback abortCallback);
|
AbortCallback abortCallback);
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
|
void waitForFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class RequestType { Image, Icon };
|
enum class RequestType { Image, Icon };
|
||||||
@@ -99,6 +100,9 @@ private:
|
|||||||
ImageCacheGeneratorInterface &generator,
|
ImageCacheGeneratorInterface &generator,
|
||||||
TimeStampProviderInterface &timeStampProvider);
|
TimeStampProviderInterface &timeStampProvider);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void wait();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Entry> m_entries;
|
std::vector<Entry> m_entries;
|
||||||
mutable std::mutex m_mutex;
|
mutable std::mutex m_mutex;
|
||||||
|
|||||||
@@ -319,4 +319,27 @@ TEST_F(ImageCache, AfterCleanNewJobsWorks)
|
|||||||
notification.wait();
|
notification.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCache, WaitForFinished)
|
||||||
|
{
|
||||||
|
ON_CALL(mockStorage, fetchImage(_, _))
|
||||||
|
.WillByDefault(Return(QmlDesigner::ImageCacheStorageInterface::Entry{image1, true}));
|
||||||
|
cache.requestImage("/path/to/Component1.qml",
|
||||||
|
mockCaptureCallback.AsStdFunction(),
|
||||||
|
mockAbortCallback.AsStdFunction());
|
||||||
|
cache.requestImage("/path/to/Component2.qml",
|
||||||
|
mockCaptureCallback.AsStdFunction(),
|
||||||
|
mockAbortCallback.AsStdFunction());
|
||||||
|
|
||||||
|
EXPECT_CALL(mockCaptureCallback, Call(_)).Times(2);
|
||||||
|
|
||||||
|
cache.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCache, WaitForFinishedInGenerator)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(mockGenerator, waitForFinished());
|
||||||
|
|
||||||
|
cache.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -247,4 +247,23 @@ TEST_F(ImageCacheGenerator, CleanIsCallingAbortCallback)
|
|||||||
waitInThread.notify();
|
waitInThread.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ImageCacheGenerator, WaitForFinished)
|
||||||
|
{
|
||||||
|
ON_CALL(collectorMock, start(_, _, _)).WillByDefault([&](auto, auto captureCallback, auto) {
|
||||||
|
captureCallback(QImage{image1});
|
||||||
|
});
|
||||||
|
generator.generateImage("name",
|
||||||
|
{11},
|
||||||
|
imageCallbackMock.AsStdFunction(),
|
||||||
|
abortCallbackMock.AsStdFunction());
|
||||||
|
generator.generateImage("name2",
|
||||||
|
{11},
|
||||||
|
imageCallbackMock.AsStdFunction(),
|
||||||
|
abortCallbackMock.AsStdFunction());
|
||||||
|
|
||||||
|
EXPECT_CALL(imageCallbackMock, Call(_)).Times(2);
|
||||||
|
|
||||||
|
generator.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -40,4 +40,5 @@ public:
|
|||||||
AbortCallback &&abortCallback),
|
AbortCallback &&abortCallback),
|
||||||
(override));
|
(override));
|
||||||
MOCK_METHOD(void, clean, (), (override));
|
MOCK_METHOD(void, clean, (), (override));
|
||||||
|
MOCK_METHOD(void, waitForFinished, (), (override));
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user