open_toontown_panda3d/direct/src/plugin/p3dPackage.h

311 lines
8.2 KiB
C++

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file p3dPackage.h
* @author drose
* @date 2009-06-12
*/
#ifndef P3DPACKAGE_H
#define P3DPACKAGE_H
#include "p3d_plugin_common.h"
#include "p3dFileDownload.h"
#include "p3dPatchfileReader.h"
#include "fileSpec.h"
#include "get_tinyxml.h"
#include <deque>
class P3DHost;
class P3DInstance;
class P3DTemporaryFile;
/**
* This corresponds to a downloadable, patchable package, and all its
* constituent files. For instance, a particular version of the Panda3D
* runtime, which consists of a bunch of dll's downloaded in a single tar
* file, is a package.
*
* The core API is responsible for managing these packages on disk,
* downloading new versions when needed, and removing stale versions to limit
* disk space waste.
*/
class P3DPackage {
private:
P3DPackage(P3DHost *host,
const string &package_name,
const string &package_version,
const string &package_platform,
const string &alt_host);
~P3DPackage();
public:
inline bool get_info_ready() const;
inline size_t get_download_size() const;
void activate_download();
inline bool get_ready() const;
inline bool get_failed() const;
inline P3DHost *get_host() const;
inline const string &get_package_dir() const;
inline const string &get_package_name() const;
inline const string &get_package_version() const;
inline const string &get_package_platform() const;
inline const string &get_package_display_name() const;
string get_formatted_name() const;
inline const TiXmlElement *get_xconfig() const;
inline const string &get_desc_file_pathname() const;
inline const string &get_desc_file_dirname() const;
inline string get_archive_file_pathname() const;
void add_instance(P3DInstance *inst);
void remove_instance(P3DInstance *inst);
void mark_used();
void uninstall();
TiXmlElement *make_xml();
private:
typedef vector<FileSpec> Extracts;
enum DownloadType {
DT_contents_file,
DT_redownload_contents_file,
DT_desc_file,
DT_install_step,
};
typedef vector<string> TryUrls;
class Download : public P3DFileDownload {
public:
Download(P3DPackage *package, DownloadType dtype,
const FileSpec &file_spec);
Download(const Download &copy);
protected:
virtual void download_progress();
virtual void download_finished(bool success);
public:
void resume_download_finished(bool success);
public:
// URL's to try downloading from, in reverse order.
TryUrls _try_urls;
private:
P3DPackage *_package;
DownloadType _dtype;
// FileSpec to validate the download against.
FileSpec _file_spec;
};
enum InstallToken {
IT_step_complete,
IT_step_failed,
IT_continue,
IT_needs_callback,
IT_terminate,
};
class InstallStep {
public:
InstallStep(P3DPackage *package, size_t bytes, double factor);
virtual ~InstallStep();
virtual InstallToken do_step(bool download_finished) = 0;
virtual void output(ostream &out) = 0;
inline double get_effort() const;
inline double get_progress() const;
inline void report_step_progress();
P3DPackage *_package;
size_t _bytes_needed;
size_t _bytes_done;
double _bytes_factor;
};
class InstallStepDownloadFile : public InstallStep {
public:
InstallStepDownloadFile(P3DPackage *package, const FileSpec &file);
virtual ~InstallStepDownloadFile();
virtual InstallToken do_step(bool download_finished);
virtual void output(ostream &out);
string _urlbase;
string _pathname;
FileSpec _file;
Download *_download;
};
class InstallStepThreaded : public InstallStep {
public:
InstallStepThreaded(P3DPackage *package, size_t bytes, double factor);
virtual ~InstallStepThreaded();
virtual InstallToken do_step(bool download_finished);
THREAD_CALLBACK_DECLARATION(InstallStepThreaded, thread_main);
void thread_main();
virtual InstallToken thread_step()=0;
void thread_set_bytes_done(size_t bytes_done);
void thread_add_bytes_done(size_t bytes_done);
THREAD _thread;
LOCK _thread_lock;
bool _thread_started;
InstallToken _thread_token;
size_t _thread_bytes_done;
};
class InstallStepUncompressFile : public InstallStepThreaded {
public:
InstallStepUncompressFile(P3DPackage *package, const FileSpec &source,
const FileSpec &target, bool verify_target);
virtual InstallToken thread_step();
virtual void output(ostream &out);
FileSpec _source;
FileSpec _target;
bool _verify_target;
};
class InstallStepUnpackArchive : public InstallStepThreaded {
public:
InstallStepUnpackArchive(P3DPackage *package, size_t unpack_size);
virtual InstallToken thread_step();
virtual void output(ostream &out);
};
class InstallStepApplyPatch : public InstallStepThreaded {
public:
InstallStepApplyPatch(P3DPackage *package,
const FileSpec &patchfile,
const FileSpec &source,
const FileSpec &target);
virtual InstallToken thread_step();
virtual void output(ostream &out);
P3DPatchfileReader _reader;
};
typedef deque<InstallStep *> InstallPlan;
typedef deque<InstallPlan> InstallPlans;
InstallPlans _install_plans;
bool _computed_plan_size;
double _total_plan_size;
double _total_plan_completed;
double _download_progress;
double _current_step_effort;
void begin_info_download();
void download_contents_file();
void contents_file_download_finished(bool success);
void redownload_contents_file(Download *download);
void contents_file_redownload_finished(bool success);
void host_got_contents_file();
void download_desc_file();
void desc_file_download_finished(bool success);
void got_desc_file(TiXmlDocument *doc, bool freshly_downloaded);
void clear_install_plans();
void build_install_plans(TiXmlDocument *doc);
void follow_install_plans(bool download_finished, bool plan_failed);
static void st_callback(void *self);
void request_callback();
void report_progress(InstallStep *step);
void report_info_ready();
void report_done(bool success);
Download *start_download(DownloadType dtype, const string &urlbase,
const string &pathname, const FileSpec &file_spec);
void set_active_download(Download *download);
void set_saved_download(Download *download);
bool is_extractable(FileSpec &file, const string &filename) const;
bool instance_terminating(P3DInstance *instance);
void set_fullname();
public:
class RequiredPackage {
public:
inline RequiredPackage(const string &package_name,
const string &package_version,
const string &package_seq,
P3DHost *host);
string _package_name;
string _package_version;
string _package_seq;
P3DHost *_host;
};
typedef vector<RequiredPackage> Requires;
Requires _requires;
private:
P3DHost *_host;
int _host_contents_iseq;
string _package_name;
string _package_version;
string _package_platform;
bool _per_platform;
int _patch_version;
string _alt_host;
bool _package_solo;
string _package_display_name;
string _package_fullname;
string _package_dir;
TiXmlElement *_xconfig;
P3DTemporaryFile *_temp_contents_file;
FileSpec _desc_file;
string _desc_file_dirname;
string _desc_file_basename;
string _desc_file_pathname;
bool _info_ready;
bool _allow_data_download;
bool _ready;
bool _failed;
Download *_active_download;
Download *_saved_download;
typedef vector<P3DInstance *> Instances;
Instances _instances;
FileSpec _compressed_archive;
FileSpec _uncompressed_archive;
size_t _unpack_size;
Extracts _extracts;
bool _updated;
static const double _download_factor;
static const double _uncompress_factor;
static const double _unpack_factor;
static const double _patch_factor;
friend class Download;
friend class InstallStep;
friend class P3DMultifileReader;
friend class P3DHost;
};
#include "p3dPackage.I"
#endif