mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-05 19:31:04 +00:00
Dynamic_Add_Media v2 (#11550)
This commit is contained in:
parent
bcb6565483
commit
bbfae0cc67
19 changed files with 796 additions and 246 deletions
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "irrlichttypes.h"
|
||||
#include "filecache.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
@ -38,7 +39,62 @@ struct HTTPFetchResult;
|
|||
bool clientMediaUpdateCache(const std::string &raw_hash,
|
||||
const std::string &filedata);
|
||||
|
||||
class ClientMediaDownloader
|
||||
// more of a base class than an interface but this name was most convenient...
|
||||
class IClientMediaDownloader
|
||||
{
|
||||
public:
|
||||
DISABLE_CLASS_COPY(IClientMediaDownloader)
|
||||
|
||||
virtual bool isStarted() const = 0;
|
||||
|
||||
// If this returns true, the downloader is done and can be deleted
|
||||
virtual bool isDone() const = 0;
|
||||
|
||||
// Add a file to the list of required file (but don't fetch it yet)
|
||||
virtual void addFile(const std::string &name, const std::string &sha1) = 0;
|
||||
|
||||
// Add a remote server to the list; ignored if not built with cURL
|
||||
virtual void addRemoteServer(const std::string &baseurl) = 0;
|
||||
|
||||
// Steps the media downloader:
|
||||
// - May load media into client by calling client->loadMedia()
|
||||
// - May check media cache for files
|
||||
// - May add files to media cache
|
||||
// - May start remote transfers by calling httpfetch_async
|
||||
// - May check for completion of current remote transfers
|
||||
// - May start conventional transfers by calling client->request_media()
|
||||
// - May inform server that all media has been loaded
|
||||
// by calling client->received_media()
|
||||
// After step has been called once, don't call addFile/addRemoteServer.
|
||||
virtual void step(Client *client) = 0;
|
||||
|
||||
// Must be called for each file received through TOCLIENT_MEDIA
|
||||
// returns true if this file belongs to this downloader
|
||||
virtual bool conventionalTransferDone(const std::string &name,
|
||||
const std::string &data, Client *client) = 0;
|
||||
|
||||
protected:
|
||||
IClientMediaDownloader();
|
||||
virtual ~IClientMediaDownloader() = default;
|
||||
|
||||
// Forwards the call to the appropriate Client method
|
||||
virtual bool loadMedia(Client *client, const std::string &data,
|
||||
const std::string &name) = 0;
|
||||
|
||||
void createCacheDirs();
|
||||
|
||||
bool tryLoadFromCache(const std::string &name, const std::string &sha1,
|
||||
Client *client);
|
||||
|
||||
bool checkAndLoad(const std::string &name, const std::string &sha1,
|
||||
const std::string &data, bool is_from_cache, Client *client);
|
||||
|
||||
// Filesystem-based media cache
|
||||
FileCache m_media_cache;
|
||||
bool m_write_to_cache;
|
||||
};
|
||||
|
||||
class ClientMediaDownloader : public IClientMediaDownloader
|
||||
{
|
||||
public:
|
||||
ClientMediaDownloader();
|
||||
|
@ -52,39 +108,29 @@ public:
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
bool isStarted() const {
|
||||
bool isStarted() const override {
|
||||
return m_initial_step_done;
|
||||
}
|
||||
|
||||
// If this returns true, the downloader is done and can be deleted
|
||||
bool isDone() const {
|
||||
bool isDone() const override {
|
||||
return m_initial_step_done &&
|
||||
m_uncached_received_count == m_uncached_count;
|
||||
}
|
||||
|
||||
// Add a file to the list of required file (but don't fetch it yet)
|
||||
void addFile(const std::string &name, const std::string &sha1);
|
||||
void addFile(const std::string &name, const std::string &sha1) override;
|
||||
|
||||
// Add a remote server to the list; ignored if not built with cURL
|
||||
void addRemoteServer(const std::string &baseurl);
|
||||
void addRemoteServer(const std::string &baseurl) override;
|
||||
|
||||
// Steps the media downloader:
|
||||
// - May load media into client by calling client->loadMedia()
|
||||
// - May check media cache for files
|
||||
// - May add files to media cache
|
||||
// - May start remote transfers by calling httpfetch_async
|
||||
// - May check for completion of current remote transfers
|
||||
// - May start conventional transfers by calling client->request_media()
|
||||
// - May inform server that all media has been loaded
|
||||
// by calling client->received_media()
|
||||
// After step has been called once, don't call addFile/addRemoteServer.
|
||||
void step(Client *client);
|
||||
void step(Client *client) override;
|
||||
|
||||
// Must be called for each file received through TOCLIENT_MEDIA
|
||||
void conventionalTransferDone(
|
||||
bool conventionalTransferDone(
|
||||
const std::string &name,
|
||||
const std::string &data,
|
||||
Client *client);
|
||||
Client *client) override;
|
||||
|
||||
protected:
|
||||
bool loadMedia(Client *client, const std::string &data,
|
||||
const std::string &name) override;
|
||||
|
||||
private:
|
||||
struct FileStatus {
|
||||
|
@ -107,13 +153,9 @@ private:
|
|||
void startRemoteMediaTransfers();
|
||||
void startConventionalTransfers(Client *client);
|
||||
|
||||
bool checkAndLoad(const std::string &name, const std::string &sha1,
|
||||
const std::string &data, bool is_from_cache,
|
||||
Client *client);
|
||||
|
||||
std::string serializeRequiredHashSet();
|
||||
static void deSerializeHashSet(const std::string &data,
|
||||
std::set<std::string> &result);
|
||||
std::string serializeRequiredHashSet();
|
||||
|
||||
// Maps filename to file status
|
||||
std::map<std::string, FileStatus*> m_files;
|
||||
|
@ -121,9 +163,6 @@ private:
|
|||
// Array of remote media servers
|
||||
std::vector<RemoteServerStatus*> m_remotes;
|
||||
|
||||
// Filesystem-based media cache
|
||||
FileCache m_media_cache;
|
||||
|
||||
// Has an attempt been made to load media files from the file cache?
|
||||
// Have hash sets been requested from remote servers?
|
||||
bool m_initial_step_done = false;
|
||||
|
@ -149,3 +188,63 @@ private:
|
|||
std::string m_name_bound = "";
|
||||
|
||||
};
|
||||
|
||||
// A media downloader that only downloads a single file.
|
||||
// It does/doesn't do several things the normal downloader does:
|
||||
// - won't fetch hash sets from remote servers
|
||||
// - will mark loaded media as coming from file push
|
||||
// - writing to file cache is optional
|
||||
class SingleMediaDownloader : public IClientMediaDownloader
|
||||
{
|
||||
public:
|
||||
SingleMediaDownloader(bool write_to_cache);
|
||||
~SingleMediaDownloader();
|
||||
|
||||
bool isStarted() const override {
|
||||
return m_stage > STAGE_INIT;
|
||||
}
|
||||
|
||||
bool isDone() const override {
|
||||
return m_stage >= STAGE_DONE;
|
||||
}
|
||||
|
||||
void addFile(const std::string &name, const std::string &sha1) override;
|
||||
|
||||
void addRemoteServer(const std::string &baseurl) override;
|
||||
|
||||
void step(Client *client) override;
|
||||
|
||||
bool conventionalTransferDone(const std::string &name,
|
||||
const std::string &data, Client *client) override;
|
||||
|
||||
protected:
|
||||
bool loadMedia(Client *client, const std::string &data,
|
||||
const std::string &name) override;
|
||||
|
||||
private:
|
||||
void initialStep(Client *client);
|
||||
void remoteMediaReceived(const HTTPFetchResult &fetch_result, Client *client);
|
||||
void startRemoteMediaTransfer();
|
||||
void startConventionalTransfer(Client *client);
|
||||
|
||||
enum Stage {
|
||||
STAGE_INIT,
|
||||
STAGE_CACHE_CHECKED, // we have tried to load the file from cache
|
||||
STAGE_DONE
|
||||
};
|
||||
|
||||
// Information about the one file we want to fetch
|
||||
std::string m_file_name;
|
||||
std::string m_file_sha1;
|
||||
s32 m_current_remote;
|
||||
|
||||
// Array of remote media servers
|
||||
std::vector<std::string> m_remotes;
|
||||
|
||||
enum Stage m_stage = STAGE_INIT;
|
||||
|
||||
// Status of remote transfers
|
||||
unsigned long m_httpfetch_caller;
|
||||
unsigned long m_httpfetch_next_id = 0;
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue