Skip to content

Commit

Permalink
display repositories asynchronously
Browse files Browse the repository at this point in the history
  • Loading branch information
p2r3 committed Oct 25, 2024
1 parent 6c761bd commit 499daaf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 21 deletions.
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ endfunction()
if (SPPLICE_TARGET_WINDOWS)
set(Qt5_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/win32/lib/cmake/Qt5")
set(Qt5Widgets_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/win32/lib/cmake/Qt5Widgets")
set(Qt5Widgets_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/win32/lib/cmake/Qt5Concurrent")
else()
set(Qt5_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/linux/lib/cmake/Qt5")
set(Qt5Widgets_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/linux/lib/cmake/Qt5Widgets")
set(Qt5Widgets_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qt5build/linux/lib/cmake/Qt5Concurrent")
endif()

# Find Qt5Widgets.
# Find required Qt5 components.
find_package(Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt5 REQUIRED COMPONENTS Concurrent)

# Add resources file
qt_add_resources(RESOURCES resources.qrc)
Expand All @@ -76,8 +79,9 @@ add_executable(SppliceCPP
${RESOURCES}
)

# Link Qt5Widgets
# Link required Qt5 components.
target_link_libraries(SppliceCPP Qt5::Widgets)
target_link_libraries(SppliceCPP Qt5::Concurrent)

# Finally, link our project's individual dependencies.
if (SPPLICE_TARGET_WINDOWS) # If building for Windows:
Expand Down
74 changes: 55 additions & 19 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <QObject>
#include <QDialog>
#include <QMessageBox>
#include <QtConcurrent>
#include <QFutureWatcher>
#include "ui/mainwindow.h"
#include "ui/repositories.h"
#include "ui/settings.h"
Expand All @@ -29,24 +31,47 @@
#include "tools/package.h"
#include "tools/repo.h"

// Fetch and display packages from the given repository URL
void displayRepository (const std::string &url, QVBoxLayout *container) {
// Fetch and display packages from the given repository URL asynchronously
void displayRepository (const std::string &url, const std::string &last, QVBoxLayout *container) {

// Fetch the repository packages // TODO: Make this asynchronous
std::vector<const ToolsPackage::PackageData*> repository = ToolsRepo::fetchRepository(url);
// Set up a watcher to fetch repository packages asynchronously
QFutureWatcher<std::vector<const ToolsPackage::PackageData*>> *watcher;
watcher = new QFutureWatcher<std::vector<const ToolsPackage::PackageData*>>(container);

// Keep track of added package count to order them properly
int currPackage = 0;
// Connect a lambda that adds the items when they've been fetched
QObject::connect(watcher, &QFutureWatcher<std::vector<const ToolsPackage::PackageData*>>::finished, container, [container, watcher, last]() {
std::vector<const ToolsPackage::PackageData*> repository = watcher->result();

for (const ToolsPackage::PackageData *package : repository) {
// Create PackageItem widget from PackageData
QWidget *item = ToolsPackage::createPackageItem(package);
// Add the item to the package list container
container->insertWidget(currPackage, item);
currPackage ++;
// Sleep for a few milliseconds on each package to reduce strain on the network
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
// Convert last fetched repository url to QString for easier comparisons
QString lastQstr = QString::fromStdString(last);
// Keep track insertion point to order packages properly
int insertAt = 0;

// Move insertion point to the top of the most recently fetched repository
while (insertAt < container->count()) {
QWidget *widget = container->itemAt(insertAt)->widget();
if (widget->property("packageRepository").toString() == lastQstr) break;
insertAt ++;
}

for (const ToolsPackage::PackageData *package : repository) {
// Create PackageItem widget from PackageData
QWidget *item = ToolsPackage::createPackageItem(package);
// Add the item to the package list container
container->insertWidget(insertAt, item);
insertAt ++;
// Sleep for a few milliseconds on each package to reduce strain on the network
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

watcher->deleteLater();
});

// Fetch the repository packages in a new thread
QFuture<std::vector<const ToolsPackage::PackageData*>> future = QtConcurrent::run([url]() {
return ToolsRepo::fetchRepository(url);
});
watcher->setFuture(future);

}

Expand Down Expand Up @@ -88,6 +113,9 @@ void checkCacheOverride (const std::filesystem::path &configPath) {

}

// A link to the index for the global Spplice repository
const std::string globalRepository = "https://p2r3.github.io/spplice-repo/index.json";

int main (int argc, char *argv[]) {

// Check for a CACHE_DIR override in cache_dir.txt
Expand Down Expand Up @@ -234,7 +262,11 @@ int main (int argc, char *argv[]) {
// Define URL submit behavior
auto submitURL = [packageContainer, urlInput, dialog]() {
const std::string url = urlInput->text().toStdString();
displayRepository(url, packageContainer);

// Insert the new repository before the topmost repository
QWidget *widget = packageContainer->itemAt(0)->widget();
displayRepository(url, widget->property("packageRepository").toString().toStdString(), packageContainer);

ToolsRepo::writeToFile(url);
dialog->hide();
};
Expand All @@ -259,13 +291,17 @@ int main (int argc, char *argv[]) {
window.setWindowTitle("Spplice");
window.show();

// Load the global repository
displayRepository("https://p2r3.github.io/spplice-repo/index.json", packageContainer);
// Load the global repository, putting it at the very bottom
displayRepository(globalRepository, "", packageContainer);

// Keep track of the previous repository to order them when fetching asynhronously
std::string lastRepository = globalRepository;

// Load additional repositories from file
std::vector<std::string> repositories = ToolsRepo::readFromFile();
for (const std::string &url : repositories) {
displayRepository(url, packageContainer);
displayRepository(url, lastRepository, packageContainer);
lastRepository = url;
}

// Clean up CURL on program termination
Expand Down

0 comments on commit 499daaf

Please sign in to comment.