From a269c15b6189a77e103fabb357640de91edf9be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Sat, 4 Nov 2017 08:50:36 +0200 Subject: [PATCH] FS|libshell|Client: Fixed connecting to server's repository The client must wait after mounting the server's repository so that the connection is fully formed and the remote folders have been populated. --- .../apps/client/src/network/serverlink.cpp | 6 +-- .../include/de/shell/packagedownloader.h | 7 +++- .../sdk/libshell/src/packagedownloader.cpp | 39 +++++++++++++++++-- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/doomsday/apps/client/src/network/serverlink.cpp b/doomsday/apps/client/src/network/serverlink.cpp index 1fbf04d583..a354c8d6cd 100644 --- a/doomsday/apps/client/src/network/serverlink.cpp +++ b/doomsday/apps/client/src/network/serverlink.cpp @@ -430,11 +430,7 @@ void ServerLink::connectToServerAndChangeGameAsync(shell::ServerInfo info) } // The server makes certain packages available for clients to download. - d->downloader.mountServerRepository(info); - - // Wait async until remote files have been populated so we can decide if - // anything needs to be downloaded. - Folder::afterPopulation([this, joinProfile, info] () + d->downloader.mountServerRepository(info, [this, joinProfile, info] (filesys::Link const *) { // Now we know all the files that the server will be providing. // If we are missing any of the packages, download a copy from the server. diff --git a/doomsday/sdk/libshell/include/de/shell/packagedownloader.h b/doomsday/sdk/libshell/include/de/shell/packagedownloader.h index de6105b011..85da7a983b 100644 --- a/doomsday/sdk/libshell/include/de/shell/packagedownloader.h +++ b/doomsday/sdk/libshell/include/de/shell/packagedownloader.h @@ -21,6 +21,7 @@ #include #include +#include #include "ServerInfo" namespace de { @@ -38,9 +39,11 @@ class LIBSHELL_PUBLIC PackageDownloader /** * Mount a server's remote file repository. * - * @param serverInfo Server information. + * @param serverInfo Server information. + * @param afterConnected Callback to call when the repository is connected and ready for use. */ - void mountServerRepository(ServerInfo const &serverInfo); + void mountServerRepository(ServerInfo const &serverInfo, + std::function afterConnected); void unmountServerRepository(); diff --git a/doomsday/sdk/libshell/src/packagedownloader.cpp b/doomsday/sdk/libshell/src/packagedownloader.cpp index 5dc208bc35..49dfae4479 100644 --- a/doomsday/sdk/libshell/src/packagedownloader.cpp +++ b/doomsday/sdk/libshell/src/packagedownloader.cpp @@ -36,11 +36,13 @@ static String const PATH_REMOTE_PACKS = "/remote/packs"; static String const PATH_REMOTE_SERVER = "/remote/server"; // local folder for RemoteFeed DENG2_PIMPL(PackageDownloader) +, DENG2_OBSERVES(filesys::RemoteFeedRelay, Status) , DENG2_OBSERVES(Asset, StateChange) , DENG2_OBSERVES(RemoteFile, Download) , DENG2_OBSERVES(Deletable, Deletion) { String fileRepository; + std::function afterConnected; bool isCancelled = false; dint64 totalBytes = 0; int numDownloads = 0; @@ -48,8 +50,26 @@ DENG2_PIMPL(PackageDownloader) QHash downloadBytes; std::function postDownloadCallback; - Impl(Public *i) : Base(i) - {} + Impl(Public *i) : Base(i) {} + + void remoteRepositoryStatusChanged(String const &address, + filesys::RemoteFeedRelay::Status) override + { + if (address == fileRepository) + { + auto *relay = &filesys::RemoteFeedRelay::get(); + relay->audienceForStatus() -= this; + + // Populate remote folders before notifying so everything is ready to go. + Folder::afterPopulation([this, relay] () + { + if (afterConnected) + { + afterConnected(relay->repository(fileRepository)); + } + }); + } + } void downloadFile(File &file) { @@ -240,7 +260,8 @@ bool PackageDownloader::isActive() const return !d->downloads.isEmpty() && !d->downloads.isReady(); } -void PackageDownloader::mountServerRepository(shell::ServerInfo const &info) +void PackageDownloader::mountServerRepository(shell::ServerInfo const &info, + std::function afterConnected) { // The remote repository feature was added in 2.1. Trying to send a RemoteFeed // request to an older server would just result in us getting immediately @@ -248,9 +269,19 @@ void PackageDownloader::mountServerRepository(shell::ServerInfo const &info) if (info.version() > Version(2, 1, 0, 2484)) { + auto &relay = filesys::RemoteFeedRelay::get(); + d->fileRepository = filesys::NativeLink::URL_SCHEME + info.address().asText(); d->isCancelled = false; - filesys::RemoteFeedRelay::get().addRepository(d->fileRepository, PATH_REMOTE_SERVER); + relay.addRepository(d->fileRepository, PATH_REMOTE_SERVER); + + // Notify after repository is available. + d->afterConnected = afterConnected; + relay.audienceForStatus() += d; + } + else if (afterConnected) + { + afterConnected(nullptr); } }