QmlDesigner: Project Storage Watcher updates only some directories

Updates only the entries for the given source context (directory) ids
and skips everything else. It is enabling partial updates
for directories in a project.

[&, &ids = ids] the strange capture clause steams from a C++ issue.

Tak-number: QDS-9456
Change-Id: Id3abcd39ac429ba4483124f334d50c2999f5e6a8
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2023-03-16 15:42:40 +01:00
parent 4c3530f5ee
commit cb0fc5fd1f
2 changed files with 98 additions and 24 deletions

View File

@@ -60,10 +60,31 @@ public:
void updateIdPaths(const std::vector<IdPaths> &idPaths) override
{
auto entriesAndIds = convertIdPathsToWatcherEntriesAndIds(idPaths);
const auto &[entires, ids] = convertIdPathsToWatcherEntriesAndIds(idPaths);
addEntries(entriesAndIds.first);
removeUnusedEntries(entriesAndIds.first, entriesAndIds.second);
addEntries(entires);
auto notContainsdId = [&, &ids = ids](WatcherEntry entry) {
return !std::binary_search(ids.begin(), ids.end(), entry.id);
};
removeUnusedEntries(entires, notContainsdId);
}
void updateContextIdPaths(const std::vector<IdPaths> &idPaths,
const SourceContextIds &sourceContextIds)
{
const auto &[entires, ids] = convertIdPathsToWatcherEntriesAndIds(idPaths);
addEntries(entires);
auto notContainsdId = [&, &ids = ids](WatcherEntry entry) {
return !std::binary_search(ids.begin(), ids.end(), entry.id)
|| !std::binary_search(sourceContextIds.begin(),
sourceContextIds.end(),
entry.sourceContextId);
};
removeUnusedEntries(entires, notContainsdId);
}
void removeIds(const ProjectPartIds &ids) override
@@ -133,9 +154,10 @@ public:
m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
}
void removeUnusedEntries(const WatcherEntries &entries, const ProjectChunkIds &ids)
template<typename Filter>
void removeUnusedEntries(const WatcherEntries &entries, Filter filter)
{
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, filter);
removeFromWatchedEntries(oldEntries);
@@ -194,10 +216,8 @@ public:
return notWatchedDirectoryIds;
}
template <typename Compare>
WatcherEntries notAnymoreWatchedEntries(
const WatcherEntries &newEntries,
Compare compare) const
template<typename Compare>
WatcherEntries notAnymoreWatchedEntries(const WatcherEntries &newEntries, Compare compare) const
{
WatcherEntries notAnymoreWatchedEntries;
notAnymoreWatchedEntries.reserve(m_watchedEntries.size());
@@ -212,16 +232,12 @@ public:
return notAnymoreWatchedEntries;
}
WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries,
const ProjectChunkIds &ids) const
template<typename Filter>
WatcherEntries notAnymoreWatchedEntriesWithIds(const WatcherEntries &newEntries, Filter filter) const
{
auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
auto newEnd = std::remove_if(oldEntries.begin(),
oldEntries.end(),
[&] (WatcherEntry entry) {
return !std::binary_search(ids.begin(), ids.end(), entry.id);
});
auto newEnd = std::remove_if(oldEntries.begin(), oldEntries.end(), filter);
oldEntries.erase(newEnd, oldEntries.end());

View File

@@ -69,7 +69,8 @@ protected:
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
ProjectChunkId projectChunkId1{ProjectPartId::create(2), SourceType::Qml};
ProjectChunkId projectChunkId2{ProjectPartId::create(2), SourceType::QmlUi};
ProjectChunkId projectChunkId3{ProjectPartId::create(4), SourceType::QmlTypes};
ProjectChunkId projectChunkId3{ProjectPartId::create(3), SourceType::QmlTypes};
ProjectChunkId projectChunkId4{ProjectPartId::create(4), SourceType::Qml};
SourcePathView path1{"/path/path1"};
SourcePathView path2{"/path/path2"};
SourcePathView path3{"/path2/path1"};
@@ -99,6 +100,11 @@ protected:
WatcherEntry watcherEntry6{projectChunkId1, sourceContextIds[1], sourceIds[2]};
WatcherEntry watcherEntry7{projectChunkId2, sourceContextIds[1], sourceIds[3]};
WatcherEntry watcherEntry8{projectChunkId3, sourceContextIds[1], sourceIds[3]};
WatcherEntry watcherEntry9{projectChunkId4, sourceContextIds[0], sourceIds[0]};
WatcherEntry watcherEntry10{projectChunkId4, sourceContextIds[0], sourceIds[1]};
WatcherEntry watcherEntry11{projectChunkId4, sourceContextIds[1], sourceIds[2]};
WatcherEntry watcherEntry12{projectChunkId4, sourceContextIds[1], sourceIds[3]};
WatcherEntry watcherEntry13{projectChunkId4, sourceContextIds[2], sourceIds[4]};
};
TEST_F(ProjectStoragePathWatcher, AddIdPaths)
@@ -310,9 +316,13 @@ TEST_F(ProjectStoragePathWatcher, RemoveOnePathForTwoId)
TEST_F(ProjectStoragePathWatcher, NotAnymoreWatchedEntriesWithId)
{
auto notContainsdId = [&](WatcherEntry entry) {
return entry.id != ids[0] && entry.id != ids[1];
};
watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
auto oldEntries = watcher.notAnymoreWatchedEntriesWithIds({watcherEntry1, watcherEntry4}, {ids[0], ids[1]});
auto oldEntries = watcher.notAnymoreWatchedEntriesWithIds({watcherEntry1, watcherEntry4},
notContainsdId);
ASSERT_THAT(oldEntries, ElementsAre(watcherEntry2, watcherEntry3));
}
@@ -386,15 +396,63 @@ TEST_F(ProjectStoragePathWatcher, NoDuplicatePathChanges)
mockQFileSytemWatcher.directoryChanged(sourceContextPath);
}
TEST_F(ProjectStoragePathWatcher, UpdateContextIdPathsAndRemoveUnusedPaths)
TEST_F(ProjectStoragePathWatcher, UpdateContextIdPathsAddsEntryInNewDirectory)
{
watcher.updateIdPaths({{projectChunkId1, {sourceIds[0], sourceIds[1]}},
{projectChunkId2, {sourceIds[0], sourceIds[1]}},
{projectChunkId3, {sourceIds[1]}}});
watcher.updateIdPaths({
{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}},
{projectChunkId4, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}},
});
watcher.updateIdPaths({{projectChunkId1, {sourceIds[0]}}, {projectChunkId2, {sourceIds[1]}}});
watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[4]}}}, {sourceContextIds[2]});
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4, watcherEntry5));
ASSERT_THAT(watcher.watchedEntries(),
UnorderedElementsAre(watcherEntry1,
watcherEntry3,
watcherEntry6,
watcherEntry9,
watcherEntry10,
watcherEntry11,
watcherEntry12,
watcherEntry13));
}
TEST_F(ProjectStoragePathWatcher, UpdateContextIdPathsAddsEntryToDirectory)
{
watcher.updateIdPaths({
{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}},
{projectChunkId4, {sourceIds[1], sourceIds[3]}},
});
watcher.updateContextIdPaths({{projectChunkId4,
{sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}}},
{sourceContextIds[1]});
ASSERT_THAT(watcher.watchedEntries(),
UnorderedElementsAre(watcherEntry1,
watcherEntry3,
watcherEntry6,
watcherEntry9,
watcherEntry10,
watcherEntry11,
watcherEntry12));
}
TEST_F(ProjectStoragePathWatcher, UpdateContextIdPathsRemovesEntry)
{
watcher.updateIdPaths({
{projectChunkId1, {sourceIds[0], sourceIds[1], sourceIds[2]}},
{projectChunkId4, {sourceIds[0], sourceIds[1], sourceIds[2], sourceIds[3]}},
});
watcher.updateContextIdPaths({{projectChunkId4, {sourceIds[3]}}}, {sourceContextIds[1]});
ASSERT_THAT(watcher.watchedEntries(),
UnorderedElementsAre(watcherEntry1,
watcherEntry3,
watcherEntry6,
watcherEntry9,
watcherEntry10,
watcherEntry12));
}
} // namespace