forked from qt-creator/qt-creator
QmlDesigner: Refresh preview image every hour
It is to assumed that the preview image will be changed and we don't need to collect the time stamps of the files. Task-number: QDS-5924 Change-Id: Icf5540d7bcc9da17a1497641f6189f35eb47f5d2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -41,6 +41,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(TimeStamp first, TimeStamp second) { return !(first == second); }
|
friend bool operator!=(TimeStamp first, TimeStamp second) { return !(first == second); }
|
||||||
|
friend bool operator<(TimeStamp first, TimeStamp second) { return first.value < second.value; }
|
||||||
|
|
||||||
|
friend TimeStamp operator+(TimeStamp first, TimeStamp second)
|
||||||
|
{
|
||||||
|
return first.value + second.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend TimeStamp operator-(TimeStamp first, TimeStamp second)
|
||||||
|
{
|
||||||
|
return first.value - second.value;
|
||||||
|
}
|
||||||
|
|
||||||
bool isValid() const { return value >= 0; }
|
bool isValid() const { return value >= 0; }
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
#include "imagecachecollector.h"
|
#include "imagecachecollector.h"
|
||||||
#include "imagecachegenerator.h"
|
#include "imagecachegenerator.h"
|
||||||
#include "imagecachestorage.h"
|
#include "imagecachestorage.h"
|
||||||
#include "timestampprovider.h"
|
#include "timestampproviderinterface.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -116,9 +116,11 @@ void AsynchronousImageFactory::request(Utils::SmallStringView name,
|
|||||||
|
|
||||||
const auto currentModifiedTime = timeStampProvider.timeStamp(name);
|
const auto currentModifiedTime = timeStampProvider.timeStamp(name);
|
||||||
const auto storageModifiedTime = storage.fetchModifiedImageTime(id);
|
const auto storageModifiedTime = storage.fetchModifiedImageTime(id);
|
||||||
|
const auto pause = timeStampProvider.pause();
|
||||||
|
|
||||||
if (currentModifiedTime == storageModifiedTime)
|
if (currentModifiedTime < (storageModifiedTime + pause))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto capture = [=](const QImage &image, const QImage &smallImage) {
|
auto capture = [=](const QImage &image, const QImage &smallImage) {
|
||||||
m_storage.storeImage(id, currentModifiedTime, image, smallImage);
|
m_storage.storeImage(id, currentModifiedTime, image, smallImage);
|
||||||
};
|
};
|
||||||
|
@@ -33,6 +33,7 @@ class TimeStampProvider : public TimeStampProviderInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sqlite::TimeStamp timeStamp(Utils::SmallStringView name) const override;
|
Sqlite::TimeStamp timeStamp(Utils::SmallStringView name) const override;
|
||||||
|
Sqlite::TimeStamp pause() const override { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -36,6 +36,7 @@ class TimeStampProviderInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Sqlite::TimeStamp timeStamp(Utils::SmallStringView name) const = 0;
|
virtual Sqlite::TimeStamp timeStamp(Utils::SmallStringView name) const = 0;
|
||||||
|
virtual Sqlite::TimeStamp pause() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~TimeStampProviderInterface() = default;
|
~TimeStampProviderInterface() = default;
|
||||||
|
@@ -50,7 +50,7 @@
|
|||||||
#include <imagecache/imagecacheconnectionmanager.h>
|
#include <imagecache/imagecacheconnectionmanager.h>
|
||||||
#include <imagecache/imagecachegenerator.h>
|
#include <imagecache/imagecachegenerator.h>
|
||||||
#include <imagecache/imagecachestorage.h>
|
#include <imagecache/imagecachestorage.h>
|
||||||
#include <imagecache/timestampprovider.h>
|
#include <imagecache/timestampproviderinterface.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
@@ -70,6 +70,23 @@ QString defaultImagePath()
|
|||||||
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
return qobject_cast<::QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TimeStampProvider : public TimeStampProviderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sqlite::TimeStamp timeStamp(Utils::SmallStringView) const override
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sqlite::TimeStamp pause() const override
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
return std::chrono::duration_cast<std::chrono::seconds>(1h).count();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class PreviewImageCacheData
|
class PreviewImageCacheData
|
||||||
|
@@ -109,14 +109,16 @@ TEST_F(AsynchronousImageFactory, RequestImageWithAuxiliaryDataRequestImageFromCo
|
|||||||
notification.wait();
|
notification.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AsynchronousImageFactory, DontRequestImageRequestImageFromCollectorIfFileWasNotUpdated)
|
TEST_F(AsynchronousImageFactory, DontRequestImageRequestImageFromCollectorIfFileWasUpdatedRecently)
|
||||||
{
|
{
|
||||||
ON_CALL(storageMock, fetchModifiedImageTime(Eq("/path/to/Component.qml"))).WillByDefault([&](auto) {
|
ON_CALL(storageMock, fetchModifiedImageTime(Eq("/path/to/Component.qml"))).WillByDefault([&](auto) {
|
||||||
notification.notify();
|
notification.notify();
|
||||||
return Sqlite::TimeStamp{124};
|
return Sqlite::TimeStamp{124};
|
||||||
});
|
});
|
||||||
ON_CALL(timeStampProviderMock, timeStamp(Eq("/path/to/Component.qml")))
|
ON_CALL(timeStampProviderMock, timeStamp(Eq("/path/to/Component.qml")))
|
||||||
.WillByDefault(Return(Sqlite::TimeStamp{124}));
|
.WillByDefault(Return(Sqlite::TimeStamp{125}));
|
||||||
|
ON_CALL(timeStampProviderMock, timeStamp(Eq("/path/to/Component.qml")))
|
||||||
|
.WillByDefault(Return(Sqlite::TimeStamp{1}));
|
||||||
|
|
||||||
EXPECT_CALL(collectorMock, start(_, _, _, _, _)).Times(0);
|
EXPECT_CALL(collectorMock, start(_, _, _, _, _)).Times(0);
|
||||||
|
|
||||||
@@ -124,6 +126,22 @@ TEST_F(AsynchronousImageFactory, DontRequestImageRequestImageFromCollectorIfFile
|
|||||||
notification.wait();
|
notification.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AsynchronousImageFactory, RequestImageRequestImageFromCollectorIfFileWasNotUpdatedRecently)
|
||||||
|
{
|
||||||
|
ON_CALL(storageMock, fetchModifiedImageTime(Eq("/path/to/Component.qml")))
|
||||||
|
.WillByDefault(Return(Sqlite::TimeStamp{123}));
|
||||||
|
ON_CALL(timeStampProviderMock, timeStamp(Eq("/path/to/Component.qml")))
|
||||||
|
.WillByDefault(Return(Sqlite::TimeStamp{125}));
|
||||||
|
ON_CALL(timeStampProviderMock, pause()).WillByDefault(Return(Sqlite::TimeStamp{1}));
|
||||||
|
|
||||||
|
EXPECT_CALL(collectorMock, start(_, _, _, _, _)).WillOnce([&](auto, auto, auto, auto, auto) {
|
||||||
|
notification.notify();
|
||||||
|
});
|
||||||
|
|
||||||
|
factory.generate("/path/to/Component.qml");
|
||||||
|
notification.wait();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(AsynchronousImageFactory, CleanRemovesEntries)
|
TEST_F(AsynchronousImageFactory, CleanRemovesEntries)
|
||||||
{
|
{
|
||||||
EXPECT_CALL(collectorMock, start(Eq("/path/to/Component1.qml"), _, _, _, _))
|
EXPECT_CALL(collectorMock, start(Eq("/path/to/Component1.qml"), _, _, _, _))
|
||||||
@@ -153,4 +171,30 @@ TEST_F(AsynchronousImageFactory, AfterCleanNewJobsWorks)
|
|||||||
notification.wait();
|
notification.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AsynchronousImageFactory, CaptureImageCallbackStoresImage)
|
||||||
|
{
|
||||||
|
ON_CALL(storageMock, fetchModifiedImageTime(Eq("/path/to/Component.qml")))
|
||||||
|
.WillByDefault(Return(Sqlite::TimeStamp{123}));
|
||||||
|
ON_CALL(timeStampProviderMock, timeStamp(Eq("/path/to/Component.qml")))
|
||||||
|
.WillByDefault(Return(Sqlite::TimeStamp{125}));
|
||||||
|
ON_CALL(timeStampProviderMock, pause()).WillByDefault(Return(Sqlite::TimeStamp{1}));
|
||||||
|
ON_CALL(collectorMock,
|
||||||
|
start(Eq("/path/to/Component.qml"),
|
||||||
|
Eq("id"),
|
||||||
|
VariantWith<Utils::monostate>(Utils::monostate{}),
|
||||||
|
_,
|
||||||
|
_))
|
||||||
|
.WillByDefault([&](auto, auto, auto, auto capture, auto) { capture(image1, smallImage1); });
|
||||||
|
|
||||||
|
EXPECT_CALL(storageMock,
|
||||||
|
storeImage(Eq("/path/to/Component.qml+id"),
|
||||||
|
Sqlite::TimeStamp{125},
|
||||||
|
Eq(image1),
|
||||||
|
Eq(smallImage1)))
|
||||||
|
.WillOnce([&](auto, auto, auto, auto) { notification.notify(); });
|
||||||
|
|
||||||
|
factory.generate("/path/to/Component.qml", "id");
|
||||||
|
notification.wait();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -33,4 +33,5 @@ class MockTimeStampProvider : public QmlDesigner::TimeStampProviderInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD(Sqlite::TimeStamp, timeStamp, (Utils::SmallStringView name), (const, override));
|
MOCK_METHOD(Sqlite::TimeStamp, timeStamp, (Utils::SmallStringView name), (const, override));
|
||||||
|
MOCK_METHOD(Sqlite::TimeStamp, pause, (), (const, override));
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user