mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
no command instance
This commit is contained in:
parent
0cce656d0b
commit
a6c1759080
@ -16,8 +16,10 @@
|
||||
#include "p3dInstanceManager.h"
|
||||
#include "p3dDownload.h"
|
||||
#include "p3dSession.h"
|
||||
#include "p3dPackage.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
int P3DInstance::_next_instance_id = 0;
|
||||
|
||||
@ -61,6 +63,14 @@ P3DInstance::
|
||||
|
||||
DESTROY_LOCK(_request_lock);
|
||||
|
||||
// Tell all of the packages that we're no longer in business for
|
||||
// them.
|
||||
Packages::iterator pi;
|
||||
for (pi = _packages.begin(); pi != _packages.end(); ++pi) {
|
||||
(*pi)->cancel_instance(this);
|
||||
}
|
||||
_packages.clear();
|
||||
|
||||
// TODO: empty _pending_requests queue and _downloads map.
|
||||
|
||||
// TODO: Is it possible for someone to delete an instance while a
|
||||
@ -239,6 +249,22 @@ feed_url_stream(int unique_id,
|
||||
return download_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::add_package
|
||||
// Access: Public
|
||||
// Description: Adds the package to the list of packages used by this
|
||||
// instance. The instance will share responsibility for
|
||||
// downloading the package will any of the other
|
||||
// instances that use the same package.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
add_package(P3DPackage *package) {
|
||||
assert(find(_packages.begin(), _packages.end(), package) == _packages.end());
|
||||
|
||||
_packages.push_back(package);
|
||||
package->set_instance(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::start_download
|
||||
// Access: Public
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
class P3DSession;
|
||||
class P3DDownload;
|
||||
class P3DPackage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DInstance
|
||||
@ -64,6 +65,8 @@ public:
|
||||
inline const string &get_session_key() const;
|
||||
inline const string &get_python_version() const;
|
||||
|
||||
void add_package(P3DPackage *package);
|
||||
|
||||
void start_download(P3DDownload *download);
|
||||
void request_stop();
|
||||
|
||||
@ -80,6 +83,9 @@ private:
|
||||
string _python_version;
|
||||
P3DSession *_session;
|
||||
|
||||
typedef vector<P3DPackage *> Packages;
|
||||
Packages _packages;
|
||||
|
||||
typedef map<int, P3DDownload *> Downloads;
|
||||
Downloads _downloads;
|
||||
|
||||
|
@ -60,20 +60,6 @@ get_platform() const {
|
||||
return _platform;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_command_instance
|
||||
// Access: Public
|
||||
// Description: Returns a global P3DInstance object that exists for
|
||||
// the lifetime of the instance manager. This instance
|
||||
// object has no reality onscreen, but can be used as a
|
||||
// download host for downloading files that aren't
|
||||
// specifically needed by any user-created instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3DInstance *P3DInstanceManager::
|
||||
get_command_instance() const {
|
||||
return _command_instance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_num_instances
|
||||
// Access: Public
|
||||
@ -84,3 +70,24 @@ inline int P3DInstanceManager::
|
||||
get_num_instances() const {
|
||||
return _instances.size();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::is_pathsep
|
||||
// Access: Private, Static
|
||||
// Description: Returns true if the indicated character is a path
|
||||
// separator character (e.g. slash or backslash), false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool P3DInstanceManager::
|
||||
is_pathsep(char ch) {
|
||||
if (ch == '/') {
|
||||
return true;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (ch == '\\') {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -54,8 +54,6 @@ P3DInstanceManager() {
|
||||
icc.dwICC = ICC_PROGRESS_CLASS;
|
||||
InitCommonControlsEx(&icc);
|
||||
#endif
|
||||
|
||||
_command_instance = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -71,8 +69,6 @@ P3DInstanceManager::
|
||||
assert(_instances.empty());
|
||||
assert(_sessions.empty());
|
||||
|
||||
delete _command_instance;
|
||||
|
||||
#ifdef _WIN32
|
||||
CloseHandle(_request_ready);
|
||||
#else
|
||||
@ -145,8 +141,6 @@ create_instance(P3D_request_ready_func *func,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
finish_instance(P3DInstance *inst) {
|
||||
assert(inst != _command_instance);
|
||||
|
||||
Instances::iterator ii;
|
||||
ii = _instances.find(inst);
|
||||
assert(ii != _instances.end());
|
||||
@ -183,10 +177,6 @@ check_request() {
|
||||
}
|
||||
}
|
||||
|
||||
if (_command_instance->has_request()) {
|
||||
return _command_instance;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -290,9 +280,11 @@ signal_request_ready() {
|
||||
// Function: P3DInstanceManager::mkdir_public
|
||||
// Access: Public, Static
|
||||
// Description: Creates a new directory with wide-open access
|
||||
// priviledges.
|
||||
// priviledges. Returns true on success, false on
|
||||
// failure. Will create intervening directories if
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
bool P3DInstanceManager::
|
||||
mkdir_public(const string &dirname) {
|
||||
#ifdef _WIN32
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
@ -302,10 +294,55 @@ mkdir_public(const string &dirname) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
CreateDirectory(dirname.c_str(), &sa);
|
||||
if (CreateDirectory(dirname.c_str(), &sa) != 0) {
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed.
|
||||
DWORD last_error = GetLastError();
|
||||
if (last_error == ERROR_ALREADY_EXISTS) {
|
||||
// Not really an error: the directory is already there.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (last_error == ERROR_PATH_NOT_FOUND) {
|
||||
// We need to make the parent directory first.
|
||||
string parent = get_dirname(dirname);
|
||||
if (!parent.empty() && mkdir_public(parent)) {
|
||||
// Parent successfully created. Try again to make the child.
|
||||
if (CreateDirectory(dirname.c_str(), &sa) != 0) {
|
||||
// Got it!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
#else //_WIN32
|
||||
mkdir(dirname.c_str(), 0777);
|
||||
if (mkdir(dirname.c_str(), 0777) == 0) {
|
||||
// Success!
|
||||
return true;
|
||||
}
|
||||
|
||||
// Failed.
|
||||
if (errno == EEXIST) {
|
||||
// Not really an error: the directory is already there.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (errno == ENOENT) {
|
||||
// We need to make the parent directory first.
|
||||
string parent = get_dirname(dirname);
|
||||
if (!parent.empty() && mkdir_public(parent)) {
|
||||
// Parent successfully created. Try again to make the child.
|
||||
if (mkdir(dirname.c_str(), 0777) == 0) {
|
||||
// Got it!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
@ -314,7 +351,9 @@ mkdir_public(const string &dirname) {
|
||||
// Function: P3DInstanceManager::mkfile_public
|
||||
// Access: Public, Static
|
||||
// Description: Creates a new file with wide-open access
|
||||
// priviledges.
|
||||
// priviledges. Returns true on success, false on
|
||||
// failure. This will create intervening directories if
|
||||
// needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DInstanceManager::
|
||||
mkfile_public(const string &filename) {
|
||||
@ -331,7 +370,17 @@ mkfile_public(const string &filename) {
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
&sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
// Try to make the parent directory first.
|
||||
string parent = get_dirname(filename);
|
||||
if (!parent.empty() && mkdir_public(parent)) {
|
||||
// Parent successfully created. Try again to make the file.
|
||||
file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
&sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
return true;
|
||||
@ -339,7 +388,15 @@ mkfile_public(const string &filename) {
|
||||
#else // _WIN32
|
||||
int fd = creat(filename.c_str(), 0777);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
// Try to make the parent directory first.
|
||||
string parent = get_dirname(filename);
|
||||
if (!parent.empty() && mkdir_public(parent)) {
|
||||
// Parent successfully created. Try again to make the file.
|
||||
fd = creat(filename.c_str(), 0777);
|
||||
}
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
@ -356,23 +413,10 @@ P3DInstanceManager *P3DInstanceManager::
|
||||
get_global_ptr() {
|
||||
if (_global_ptr == NULL) {
|
||||
_global_ptr = new P3DInstanceManager;
|
||||
_global_ptr->create_command_instance();
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::create_command_instance;
|
||||
// Access: Private
|
||||
// Description: Create a command instance. This is used to handle
|
||||
// requests that have nothing to do with any particular
|
||||
// host-created instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
create_command_instance() {
|
||||
_command_instance = new P3DInstance(NULL, "", NULL, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::find_root_dir
|
||||
// Access: Private
|
||||
@ -488,4 +532,23 @@ find_root_dir() const {
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_dirname
|
||||
// Access: Private, Static
|
||||
// Description: Returns the directory component of the indicated
|
||||
// pathname, or the empty string if there is no
|
||||
// directory prefix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string P3DInstanceManager::
|
||||
get_dirname(const string &filename) {
|
||||
size_t p = filename.length();
|
||||
while (p > 0) {
|
||||
--p;
|
||||
if (is_pathsep(filename[p])) {
|
||||
return filename.substr(0, p);
|
||||
}
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
|
@ -58,20 +58,20 @@ public:
|
||||
const string &package_version,
|
||||
const string &package_display_name);
|
||||
|
||||
inline P3DInstance *get_command_instance() const;
|
||||
inline int get_num_instances() const;
|
||||
|
||||
int get_unique_session_index();
|
||||
void signal_request_ready();
|
||||
|
||||
static void mkdir_public(const string &dirname);
|
||||
static bool mkdir_public(const string &dirname);
|
||||
static bool mkfile_public(const string &dirname);
|
||||
|
||||
static P3DInstanceManager *get_global_ptr();
|
||||
|
||||
private:
|
||||
void create_command_instance();
|
||||
string find_root_dir() const;
|
||||
static inline bool is_pathsep(char ch);
|
||||
static string get_dirname(const string &filename);
|
||||
|
||||
private:
|
||||
bool _is_initialized;
|
||||
@ -79,8 +79,6 @@ private:
|
||||
string _download_url;
|
||||
string _platform;
|
||||
|
||||
P3DInstance *_command_instance;
|
||||
|
||||
typedef set<P3DInstance *> Instances;
|
||||
Instances _instances;
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "p3dPackage.h"
|
||||
#include "p3dInstanceManager.h"
|
||||
#include "p3dInstance.h"
|
||||
#include "p3dMultifileReader.h"
|
||||
|
||||
#include "openssl/md5.h"
|
||||
@ -81,23 +82,6 @@ P3DPackage(const string &package_name, const string &package_version,
|
||||
|
||||
_desc_file_basename = _package_fullname + ".xml";
|
||||
_desc_file_pathname = _package_dir + "/" + _desc_file_basename;
|
||||
|
||||
// TODO: we should check the desc file for updates with the server.
|
||||
// Perhaps this should be done in a parent class.
|
||||
|
||||
// TODO: if the desc file exists, and is consistent with the server
|
||||
// contents file, don't re-download it.
|
||||
/*
|
||||
// Load the desc file, if it exists.
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (!doc.LoadFile()) {
|
||||
download_desc_file();
|
||||
} else {
|
||||
got_desc_file(&doc, false);
|
||||
}
|
||||
*/
|
||||
|
||||
download_desc_file();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -116,6 +100,8 @@ P3DPackage::
|
||||
delete _active_download;
|
||||
_active_download = NULL;
|
||||
}
|
||||
|
||||
assert(_instances.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -155,6 +141,87 @@ cancel_callback(Callback *callback) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::set_instance
|
||||
// Access: Public
|
||||
// Description: Specifies an instance that may be responsible for
|
||||
// downloading this package.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPackage::
|
||||
set_instance(P3DInstance *inst) {
|
||||
_instances.push_back(inst);
|
||||
|
||||
begin_download();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::cancel_instance
|
||||
// Access: Public
|
||||
// Description: Indicates that the given instance will no longer be
|
||||
// responsible for downloading this package.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPackage::
|
||||
cancel_instance(P3DInstance *inst) {
|
||||
assert(!_instances.empty());
|
||||
|
||||
if (inst == _instances[0]) {
|
||||
// This was the primary instance. Cancel any pending download and
|
||||
// move to the next instance.
|
||||
if (_active_download != NULL) {
|
||||
_active_download->cancel();
|
||||
delete _active_download;
|
||||
_active_download = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Instances::iterator ii = find(_instances.begin(), _instances.end(), inst);
|
||||
assert(ii != _instances.end());
|
||||
_instances.erase(ii);
|
||||
|
||||
begin_download();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::begin_download
|
||||
// Access: Public
|
||||
// Description: Begins downloading and installing the package, if
|
||||
// needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPackage::
|
||||
begin_download() {
|
||||
if (_instances.empty()) {
|
||||
// Can't download without any instances.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ready) {
|
||||
// Already downloaded.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_active_download != NULL) {
|
||||
// In the middle of downloading.
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: we should check the desc file for updates with the server.
|
||||
// Perhaps this should be done in a parent class.
|
||||
|
||||
// TODO: if the desc file exists, and is consistent with the server
|
||||
// contents file, don't re-download it.
|
||||
/*
|
||||
// Load the desc file, if it exists.
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (!doc.LoadFile()) {
|
||||
download_desc_file();
|
||||
} else {
|
||||
got_desc_file(&doc, false);
|
||||
}
|
||||
*/
|
||||
|
||||
download_desc_file();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::download_desc_file
|
||||
// Access: Private
|
||||
@ -554,8 +621,10 @@ start_download(P3DPackage::DownloadType dtype, const string &url,
|
||||
|
||||
_active_download = download;
|
||||
_partial_download = false;
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
inst_mgr->get_command_instance()->start_download(download);
|
||||
|
||||
assert(!_instances.empty());
|
||||
|
||||
_instances[0]->start_download(download);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "p3d_plugin_common.h"
|
||||
#include "p3dFileDownload.h"
|
||||
|
||||
class P3DInstance;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DPackage
|
||||
// Description : This corresponds to a downloadable, patchable
|
||||
@ -54,6 +56,9 @@ public:
|
||||
void set_callback(Callback *callback);
|
||||
void cancel_callback(Callback *callback);
|
||||
|
||||
void set_instance(P3DInstance *inst);
|
||||
void cancel_instance(P3DInstance *inst);
|
||||
|
||||
private:
|
||||
enum DownloadType {
|
||||
DT_desc_file,
|
||||
@ -73,6 +78,7 @@ private:
|
||||
DownloadType _dtype;
|
||||
};
|
||||
|
||||
void begin_download();
|
||||
void download_desc_file();
|
||||
void desc_file_download_finished(bool success);
|
||||
void got_desc_file(TiXmlDocument *doc, bool freshly_downloaded);
|
||||
@ -115,6 +121,9 @@ private:
|
||||
typedef vector<Callback *> Callbacks;
|
||||
Callbacks _callbacks;
|
||||
|
||||
typedef vector<P3DInstance *> Instances;
|
||||
Instances _instances;
|
||||
|
||||
enum { hash_size = 16 };
|
||||
|
||||
class FileSpec {
|
||||
|
@ -52,6 +52,8 @@ P3DSession(P3DInstance *inst) {
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
_panda3d = inst_mgr->get_package("panda3d", "dev", "Panda3D");
|
||||
inst->add_package(_panda3d);
|
||||
|
||||
_panda3d_callback = NULL;
|
||||
_python_root_dir = _panda3d->get_package_dir();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user