mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
better download rules
This commit is contained in:
parent
ee47d35695
commit
7293844e4a
@ -123,7 +123,8 @@ static void unload_dso();
|
|||||||
// path.
|
// path.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool
|
bool
|
||||||
load_plugin(const string &p3d_plugin_filename) {
|
load_plugin(const string &p3d_plugin_filename,
|
||||||
|
const string &contents_filename) {
|
||||||
string filename = p3d_plugin_filename;
|
string filename = p3d_plugin_filename;
|
||||||
if (filename.empty()) {
|
if (filename.empty()) {
|
||||||
// Look for the plugin along the path.
|
// Look for the plugin along the path.
|
||||||
@ -292,26 +293,7 @@ load_plugin(const string &p3d_plugin_filename) {
|
|||||||
// Successfully loaded.
|
// Successfully loaded.
|
||||||
plugin_loaded = true;
|
plugin_loaded = true;
|
||||||
|
|
||||||
#ifdef P3D_PLUGIN_LOGFILE2
|
if (!P3D_initialize(P3D_API_VERSION, contents_filename.c_str())) {
|
||||||
string logfilename = P3D_PLUGIN_LOGFILE2;
|
|
||||||
#else
|
|
||||||
string logfilename;
|
|
||||||
#endif // P3D_PLUGIN_LOGFILE2
|
|
||||||
|
|
||||||
if (logfilename.empty()) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
static const size_t buffer_size = 4096;
|
|
||||||
char buffer[buffer_size];
|
|
||||||
if (GetTempPath(buffer_size, buffer) != 0) {
|
|
||||||
logfilename = buffer;
|
|
||||||
logfilename += "panda3d.2.log";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
logfilename = "/tmp/panda3d.2.log";
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!P3D_initialize(P3D_API_VERSION, logfilename.c_str())) {
|
|
||||||
// Oops, failure to initialize.
|
// Oops, failure to initialize.
|
||||||
cerr << "Failed to initialize plugin (wrong API version?)\n";
|
cerr << "Failed to initialize plugin (wrong API version?)\n";
|
||||||
unload_plugin();
|
unload_plugin();
|
||||||
|
@ -58,7 +58,8 @@ extern P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream;
|
|||||||
extern P3D_instance_handle_event_func *P3D_instance_handle_event;
|
extern P3D_instance_handle_event_func *P3D_instance_handle_event;
|
||||||
|
|
||||||
string get_plugin_basename();
|
string get_plugin_basename();
|
||||||
bool load_plugin(const string &p3d_plugin_filename);
|
bool load_plugin(const string &p3d_plugin_filename,
|
||||||
|
const string &contents_filename);
|
||||||
void unload_plugin();
|
void unload_plugin();
|
||||||
bool is_plugin_loaded();
|
bool is_plugin_loaded();
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ class ContentsMaker:
|
|||||||
print >> f, '<?xml version="1.0" ?>'
|
print >> f, '<?xml version="1.0" ?>'
|
||||||
print >> f, ''
|
print >> f, ''
|
||||||
print >> f, '<contents>'
|
print >> f, '<contents>'
|
||||||
for packageName, packageVersion, packagePlatform, file in self.packages:
|
for packageName, packagePlatform, packageVersion, file in self.packages:
|
||||||
print >> f, ' <package name="%s" version="%s" platform="%s" %s />' % (
|
print >> f, ' <package name="%s" platform="%s" version="%s" %s />' % (
|
||||||
packageName, packageVersion, packagePlatform or '', file.getParams())
|
packageName, packagePlatform or '', packageVersion, file.getParams())
|
||||||
print >> f, '</contents>'
|
print >> f, '</contents>'
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
@ -93,14 +93,14 @@ class ContentsMaker:
|
|||||||
file = FileSpec(localpath + xml,
|
file = FileSpec(localpath + xml,
|
||||||
Filename(self.stageDir, localpath + xml))
|
Filename(self.stageDir, localpath + xml))
|
||||||
print file.filename
|
print file.filename
|
||||||
self.packages.append((packageName, packageVersion, packagePlatform, file))
|
self.packages.append((packageName, packagePlatform, packageVersion, file))
|
||||||
|
|
||||||
if localpath.count('/') == 3:
|
if localpath.count('/') == 3:
|
||||||
packageName, packageVersion, packagePlatform, junk = localpath.split('/')
|
packageName, packagePlatform, packageVersion, junk = localpath.split('/')
|
||||||
file = FileSpec(localpath + xml,
|
file = FileSpec(localpath + xml,
|
||||||
Filename(self.stageDir, localpath + xml))
|
Filename(self.stageDir, localpath + xml))
|
||||||
print file.filename
|
print file.filename
|
||||||
self.packages.append((packageName, packageVersion, packagePlatform, file))
|
self.packages.append((packageName, packagePlatform, packageVersion, file))
|
||||||
|
|
||||||
|
|
||||||
def makeContents(args):
|
def makeContents(args):
|
||||||
|
@ -77,8 +77,9 @@ class PackageMaker:
|
|||||||
self.packageStageDir = Filename(self.stageDir, '%s/%s' % (self.packageName, self.packageVersion))
|
self.packageStageDir = Filename(self.stageDir, '%s/%s' % (self.packageName, self.packageVersion))
|
||||||
|
|
||||||
if self.packagePlatform:
|
if self.packagePlatform:
|
||||||
self.packageFullname += '_%s' % (self.packagePlatform)
|
self.packageFullname = '%s_%s_%s' % (
|
||||||
self.packageStageDir = Filename(self.packageStageDir, self.packagePlatform)
|
self.packageName, self.packagePlatform, self.packageVersion)
|
||||||
|
self.packageStageDir = Filename(self.stageDir, '%s/%s/%s' % (self.packageName, self.packagePlatform, self.packageVersion))
|
||||||
|
|
||||||
Filename(self.packageStageDir, '.').makeDir()
|
Filename(self.packageStageDir, '.').makeDir()
|
||||||
self.cleanDir(self.packageStageDir)
|
self.cleanDir(self.packageStageDir)
|
||||||
@ -121,7 +122,7 @@ class PackageMaker:
|
|||||||
f = open(descFilePathname.toOsSpecific(), 'w')
|
f = open(descFilePathname.toOsSpecific(), 'w')
|
||||||
print >> f, '<?xml version="1.0" ?>'
|
print >> f, '<?xml version="1.0" ?>'
|
||||||
print >> f, ''
|
print >> f, ''
|
||||||
print >> f, '<package name="%s" version="%s" platform="%s">' % (self.packageName, self.packageVersion, self.packagePlatform or '')
|
print >> f, '<package name="%s" platform="%s" version="%s">' % (self.packageName, self.packagePlatform or '', self.packageVersion)
|
||||||
print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.getParams())
|
print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.getParams())
|
||||||
print >> f, ' <compressed_archive %s />' % (compressedArchive.getParams())
|
print >> f, ' <compressed_archive %s />' % (compressedArchive.getParams())
|
||||||
for file in self.components:
|
for file in self.components:
|
||||||
@ -209,9 +210,9 @@ def makePackage(args):
|
|||||||
if len(tokens) >= 1:
|
if len(tokens) >= 1:
|
||||||
pm.packageName = tokens[0]
|
pm.packageName = tokens[0]
|
||||||
if len(tokens) >= 2:
|
if len(tokens) >= 2:
|
||||||
pm.packageVersion = tokens[1]
|
|
||||||
if len(tokens) >= 3:
|
|
||||||
pm.packagePlatform = tokens[2]
|
pm.packagePlatform = tokens[2]
|
||||||
|
if len(tokens) >= 3:
|
||||||
|
pm.packageVersion = tokens[1]
|
||||||
if len(tokens) >= 4:
|
if len(tokens) >= 4:
|
||||||
raise ArgumentError, 'Too many tokens in string: %s' % (value)
|
raise ArgumentError, 'Too many tokens in string: %s' % (value)
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ mkdir_complete(const string &dirname, ostream &logfile) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
#else //_WIN32
|
#else //_WIN32
|
||||||
if (mkdir(dirname.c_str(), 0777) == 0) {
|
if (mkdir(dirname.c_str(), 0755) == 0) {
|
||||||
// Success!
|
// Success!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ mkdir_complete(const string &dirname, ostream &logfile) {
|
|||||||
string parent = get_dirname(dirname);
|
string parent = get_dirname(dirname);
|
||||||
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
||||||
// Parent successfully created. Try again to make the child.
|
// Parent successfully created. Try again to make the child.
|
||||||
if (mkdir(dirname.c_str(), 0777) == 0) {
|
if (mkdir(dirname.c_str(), 0755) == 0) {
|
||||||
// Got it!
|
// Got it!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -147,13 +147,13 @@ mkfile_complete(const string &filename, ostream &logfile) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
int fd = creat(filename.c_str(), 0777);
|
int fd = creat(filename.c_str(), 0755);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
// Try to make the parent directory first.
|
// Try to make the parent directory first.
|
||||||
string parent = get_dirname(filename);
|
string parent = get_dirname(filename);
|
||||||
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
if (!parent.empty() && mkdir_complete(parent, logfile)) {
|
||||||
// Parent successfully created. Try again to make the file.
|
// Parent successfully created. Try again to make the file.
|
||||||
fd = creat(filename.c_str(), 0777);
|
fd = creat(filename.c_str(), 0755);
|
||||||
}
|
}
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
logfile
|
logfile
|
||||||
|
@ -131,6 +131,8 @@ download_progress() {
|
|||||||
if (now != _last_reported_time || true) {
|
if (now != _last_reported_time || true) {
|
||||||
_last_reported_time = now;
|
_last_reported_time = now;
|
||||||
}
|
}
|
||||||
|
nout << "Downloading " << get_url() << ": "
|
||||||
|
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -143,6 +145,6 @@ download_progress() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DDownload::
|
void P3DDownload::
|
||||||
download_finished(bool success) {
|
download_finished(bool success) {
|
||||||
nout << "Downloading " << get_url() << ": "
|
nout << "Downloaded " << get_url() << ": "
|
||||||
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
||||||
}
|
}
|
||||||
|
@ -25,15 +25,47 @@ P3DFileParams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DFileParams::Constructor
|
// Function: P3DFileParams::Copy Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DFileParams::
|
P3DFileParams::
|
||||||
P3DFileParams(const string &p3d_filename,
|
P3DFileParams(const P3DFileParams ©) :
|
||||||
const P3D_token tokens[], size_t num_tokens) :
|
_p3d_filename(copy._p3d_filename),
|
||||||
_p3d_filename(p3d_filename)
|
_tokens(copy._tokens)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DFileParams::Copy Assignment
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DFileParams::
|
||||||
|
operator = (const P3DFileParams &other) {
|
||||||
|
_p3d_filename = other._p3d_filename;
|
||||||
|
_tokens = other._tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DFileParams::set_p3d_filename
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the file that contains the instance data.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DFileParams::
|
||||||
|
set_p3d_filename(const string &p3d_filename) {
|
||||||
|
_p3d_filename = p3d_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DFileParams::set_tokens
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the tokens associated with the instance.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DFileParams::
|
||||||
|
set_tokens(const P3D_token tokens[], size_t num_tokens) {
|
||||||
|
_tokens.clear();
|
||||||
|
|
||||||
for (size_t i = 0; i < num_tokens; ++i) {
|
for (size_t i = 0; i < num_tokens; ++i) {
|
||||||
Token token;
|
Token token;
|
||||||
if (tokens[i]._keyword != NULL) {
|
if (tokens[i]._keyword != NULL) {
|
||||||
@ -50,17 +82,6 @@ P3DFileParams(const string &p3d_filename,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: P3DFileParams::Copy Assignment
|
|
||||||
// Access: Public
|
|
||||||
// Description:
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void P3DFileParams::
|
|
||||||
operator = (const P3DFileParams &other) {
|
|
||||||
_p3d_filename = other._p3d_filename;
|
|
||||||
_tokens = other._tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DFileParams::lookup_token
|
// Function: P3DFileParams::lookup_token
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -27,11 +27,12 @@
|
|||||||
class P3DFileParams {
|
class P3DFileParams {
|
||||||
public:
|
public:
|
||||||
P3DFileParams();
|
P3DFileParams();
|
||||||
P3DFileParams(const string &p3d_filename,
|
P3DFileParams(const P3DFileParams ©);
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
|
||||||
|
|
||||||
void operator = (const P3DFileParams &other);
|
void operator = (const P3DFileParams &other);
|
||||||
|
|
||||||
|
void set_p3d_filename(const string &p3d_filename);
|
||||||
|
void set_tokens(const P3D_token tokens[], size_t num_tokens);
|
||||||
|
|
||||||
inline const string &get_p3d_filename() const;
|
inline const string &get_p3d_filename() const;
|
||||||
string lookup_token(const string &keyword) const;
|
string lookup_token(const string &keyword) const;
|
||||||
bool has_token(const string &keyword) const;
|
bool has_token(const string &keyword) const;
|
||||||
|
@ -49,7 +49,8 @@ typedef P3DSplashWindow SplashWindowType;
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DInstance::
|
P3DInstance::
|
||||||
P3DInstance(P3D_request_ready_func *func, void *user_data) :
|
P3DInstance(P3D_request_ready_func *func,
|
||||||
|
const P3D_token tokens[], size_t num_tokens, void *user_data) :
|
||||||
_func(func)
|
_func(func)
|
||||||
{
|
{
|
||||||
_browser_script_object = NULL;
|
_browser_script_object = NULL;
|
||||||
@ -59,6 +60,8 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
|
|||||||
_got_fparams = false;
|
_got_fparams = false;
|
||||||
_got_wparams = false;
|
_got_wparams = false;
|
||||||
|
|
||||||
|
_fparams.set_tokens(tokens, num_tokens);
|
||||||
|
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
_instance_id = inst_mgr->get_unique_id();
|
_instance_id = inst_mgr->get_unique_id();
|
||||||
|
|
||||||
@ -137,16 +140,17 @@ P3DInstance::
|
|||||||
// download is still running? Who will crash when this happens?
|
// download is still running? Who will crash when this happens?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::set_fparams
|
// Function: P3DInstance::set_p3d_filename
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Sets up the initial file parameters for the instance.
|
// Description: Specifies the file that contains the instance data.
|
||||||
// Normally this is only called once.
|
// Normally this is only called once.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
set_fparams(const P3DFileParams &fparams) {
|
set_p3d_filename(const string &p3d_filename) {
|
||||||
_got_fparams = true;
|
_got_fparams = true;
|
||||||
_fparams = fparams;
|
_fparams.set_p3d_filename(p3d_filename);
|
||||||
|
|
||||||
// This also sets up some internal data based on the contents of the
|
// This also sets up some internal data based on the contents of the
|
||||||
// above file and the associated tokens.
|
// above file and the associated tokens.
|
||||||
@ -176,13 +180,6 @@ set_fparams(const P3DFileParams &fparams) {
|
|||||||
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
|
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
|
||||||
P3D_OBJECT_XDECREF(result);
|
P3D_OBJECT_XDECREF(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe create the splash window.
|
|
||||||
if (!_instance_window_opened && _got_wparams) {
|
|
||||||
if (_splash_window == NULL) {
|
|
||||||
make_splash_window();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -198,7 +195,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
_wparams = wparams;
|
_wparams = wparams;
|
||||||
|
|
||||||
// Update or create the splash window.
|
// Update or create the splash window.
|
||||||
if (!_instance_window_opened && _got_fparams) {
|
if (!_instance_window_opened) {
|
||||||
if (_splash_window == NULL) {
|
if (_splash_window == NULL) {
|
||||||
make_splash_window();
|
make_splash_window();
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,11 @@ class P3DToplevelObject;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DInstance : public P3D_instance, public P3DReferenceCount {
|
class P3DInstance : public P3D_instance, public P3DReferenceCount {
|
||||||
public:
|
public:
|
||||||
P3DInstance(P3D_request_ready_func *func, void *user_data);
|
P3DInstance(P3D_request_ready_func *func,
|
||||||
|
const P3D_token tokens[], size_t num_tokens, void *user_data);
|
||||||
~P3DInstance();
|
~P3DInstance();
|
||||||
|
|
||||||
void set_fparams(const P3DFileParams &fparams);
|
void set_p3d_filename(const string &p3d_filename);
|
||||||
inline const P3DFileParams &get_fparams() const;
|
inline const P3DFileParams &get_fparams() const;
|
||||||
|
|
||||||
void set_wparams(const P3DWindowParams &wparams);
|
void set_wparams(const P3DWindowParams &wparams);
|
||||||
|
@ -60,6 +60,17 @@ get_platform() const {
|
|||||||
return _platform;
|
return _platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstanceManager::has_contents_file
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if a contents.xml file has been
|
||||||
|
// successfully read, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
inline bool P3DInstanceManager::
|
||||||
|
has_contents_file() const {
|
||||||
|
return (_xcontents != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstanceManager::get_num_instances
|
// Function: P3DInstanceManager::get_num_instances
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#include "p3dNoneObject.h"
|
#include "p3dNoneObject.h"
|
||||||
#include "p3dBoolObject.h"
|
#include "p3dBoolObject.h"
|
||||||
#include "find_root_dir.h"
|
#include "find_root_dir.h"
|
||||||
|
#include "mkdir_complete.h"
|
||||||
|
#include "fileSpec.h"
|
||||||
|
#include "get_tinyxml.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
@ -40,6 +43,7 @@ P3DInstanceManager::
|
|||||||
P3DInstanceManager() {
|
P3DInstanceManager() {
|
||||||
_is_initialized = false;
|
_is_initialized = false;
|
||||||
_unique_id = 0;
|
_unique_id = 0;
|
||||||
|
_xcontents = NULL;
|
||||||
|
|
||||||
_notify_thread_continue = false;
|
_notify_thread_continue = false;
|
||||||
_started_notify_thread = false;
|
_started_notify_thread = false;
|
||||||
@ -77,6 +81,10 @@ P3DInstanceManager::
|
|||||||
_started_notify_thread = false;
|
_started_notify_thread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_xcontents != NULL) {
|
||||||
|
delete _xcontents;
|
||||||
|
}
|
||||||
|
|
||||||
assert(_instances.empty());
|
assert(_instances.empty());
|
||||||
assert(_sessions.empty());
|
assert(_sessions.empty());
|
||||||
|
|
||||||
@ -112,13 +120,14 @@ P3DInstanceManager::
|
|||||||
// redownloaded.
|
// redownloaded.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DInstanceManager::
|
bool P3DInstanceManager::
|
||||||
initialize() {
|
initialize(const string &contents_filename) {
|
||||||
_root_dir = find_root_dir();
|
_root_dir = find_root_dir();
|
||||||
_download_url = P3D_PLUGIN_DOWNLOAD;
|
_download_url = P3D_PLUGIN_DOWNLOAD;
|
||||||
_platform = P3D_PLUGIN_PLATFORM;
|
_platform = P3D_PLUGIN_PLATFORM;
|
||||||
|
|
||||||
nout << "_root_dir = " << _root_dir << ", download = "
|
nout << "_root_dir = " << _root_dir
|
||||||
<< _download_url << "\n";
|
<< ", download = " << _download_url
|
||||||
|
<< ", contents = " << contents_filename << "\n";
|
||||||
|
|
||||||
if (_root_dir.empty()) {
|
if (_root_dir.empty()) {
|
||||||
nout << "Could not find root directory.\n";
|
nout << "Could not find root directory.\n";
|
||||||
@ -127,6 +136,47 @@ initialize() {
|
|||||||
|
|
||||||
_is_initialized = true;
|
_is_initialized = true;
|
||||||
|
|
||||||
|
// Attempt to read the supplied contents.xml file.
|
||||||
|
if (!contents_filename.empty()) {
|
||||||
|
if (!read_contents_file(contents_filename)) {
|
||||||
|
nout << "Couldn't read " << contents_filename << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstanceManager::read_contents_file
|
||||||
|
// Access: Public
|
||||||
|
// Description: Reads the contents.xml file in the indicated
|
||||||
|
// filename. On success, copies the contents.xml file
|
||||||
|
// into the standard location.
|
||||||
|
//
|
||||||
|
// Returns true on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstanceManager::
|
||||||
|
read_contents_file(const string &contents_filename) {
|
||||||
|
TiXmlDocument doc(contents_filename.c_str());
|
||||||
|
if (!doc.LoadFile()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlElement *xcontents = doc.FirstChildElement("contents");
|
||||||
|
if (xcontents == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_xcontents != NULL) {
|
||||||
|
delete _xcontents;
|
||||||
|
}
|
||||||
|
_xcontents = (TiXmlElement *)xcontents->Clone();
|
||||||
|
|
||||||
|
string standard_filename = _root_dir + "/contents.xml";
|
||||||
|
if (standard_filename != contents_filename) {
|
||||||
|
copy_file(contents_filename, standard_filename);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +187,10 @@ initialize() {
|
|||||||
// indicated startup information.
|
// indicated startup information.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DInstance *P3DInstanceManager::
|
P3DInstance *P3DInstanceManager::
|
||||||
create_instance(P3D_request_ready_func *func, void *user_data) {
|
create_instance(P3D_request_ready_func *func,
|
||||||
P3DInstance *inst = new P3DInstance(func, user_data);
|
const P3D_token tokens[], size_t num_tokens,
|
||||||
|
void *user_data) {
|
||||||
|
P3DInstance *inst = new P3DInstance(func, tokens, num_tokens, user_data);
|
||||||
inst->ref();
|
inst->ref();
|
||||||
_instances.insert(inst);
|
_instances.insert(inst);
|
||||||
|
|
||||||
@ -154,13 +206,12 @@ create_instance(P3D_request_ready_func *func, void *user_data) {
|
|||||||
// particular instance.
|
// particular instance.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool P3DInstanceManager::
|
bool P3DInstanceManager::
|
||||||
start_instance(P3DInstance *inst, const string &p3d_filename,
|
start_instance(P3DInstance *inst, const string &p3d_filename) {
|
||||||
const P3D_token tokens[], size_t num_tokens) {
|
|
||||||
if (inst->is_started()) {
|
if (inst->is_started()) {
|
||||||
nout << "Instance started twice: " << inst << "\n";
|
nout << "Instance started twice: " << inst << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inst->set_fparams(P3DFileParams(p3d_filename, tokens, num_tokens));
|
inst->set_p3d_filename(p3d_filename);
|
||||||
|
|
||||||
P3DSession *session;
|
P3DSession *session;
|
||||||
Sessions::iterator si = _sessions.find(inst->get_session_key());
|
Sessions::iterator si = _sessions.find(inst->get_session_key());
|
||||||
@ -192,16 +243,17 @@ finish_instance(P3DInstance *inst) {
|
|||||||
_instances.erase(ii);
|
_instances.erase(ii);
|
||||||
|
|
||||||
Sessions::iterator si = _sessions.find(inst->get_session_key());
|
Sessions::iterator si = _sessions.find(inst->get_session_key());
|
||||||
assert(si != _sessions.end());
|
if (si != _sessions.end()) {
|
||||||
P3DSession *session = (*si).second;
|
P3DSession *session = (*si).second;
|
||||||
session->terminate_instance(inst);
|
session->terminate_instance(inst);
|
||||||
|
|
||||||
// If that was the last instance in this session, terminate the
|
// If that was the last instance in this session, terminate the
|
||||||
// session.
|
// session.
|
||||||
if (session->get_num_instances() == 0) {
|
if (session->get_num_instances() == 0) {
|
||||||
_sessions.erase(session->get_session_key());
|
_sessions.erase(session->get_session_key());
|
||||||
session->shutdown();
|
session->shutdown();
|
||||||
unref_delete(session);
|
unref_delete(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unref_delete(inst);
|
unref_delete(inst);
|
||||||
@ -284,20 +336,61 @@ P3DPackage *P3DInstanceManager::
|
|||||||
get_package(const string &package_name, const string &package_version,
|
get_package(const string &package_name, const string &package_version,
|
||||||
const string &package_display_name) {
|
const string &package_display_name) {
|
||||||
string package_platform = get_platform();
|
string package_platform = get_platform();
|
||||||
string key = package_name + "_" + package_version + "_" + package_platform;
|
string key = package_name + "_" + package_platform + "_" + package_version;
|
||||||
Packages::iterator pi = _packages.find(key);
|
Packages::iterator pi = _packages.find(key);
|
||||||
if (pi != _packages.end()) {
|
if (pi != _packages.end()) {
|
||||||
return (*pi).second;
|
return (*pi).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
P3DPackage *package = new P3DPackage(package_name, package_version,
|
P3DPackage *package = new P3DPackage(package_name, package_platform,
|
||||||
package_platform, package_display_name);
|
package_version, package_display_name);
|
||||||
bool inserted = _packages.insert(Packages::value_type(key, package)).second;
|
bool inserted = _packages.insert(Packages::value_type(key, package)).second;
|
||||||
assert(inserted);
|
assert(inserted);
|
||||||
|
|
||||||
return package;
|
return package;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstanceManager::get_package_desc_file
|
||||||
|
// Access: Public
|
||||||
|
// Description: Fills the indicated FileSpec with the hash
|
||||||
|
// information for the package's desc file. Returns
|
||||||
|
// true if successful, false if the package is unknown.
|
||||||
|
// This requires has_contents_file() to return true in
|
||||||
|
// order to be successful.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstanceManager::
|
||||||
|
get_package_desc_file(FileSpec &desc_file,
|
||||||
|
const string &package_name,
|
||||||
|
const string &package_version) {
|
||||||
|
if (_xcontents == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string package_platform = get_platform();
|
||||||
|
|
||||||
|
// Scan the contents data for the indicated package.
|
||||||
|
TiXmlElement *xpackage = _xcontents->FirstChildElement("package");
|
||||||
|
while (xpackage != NULL) {
|
||||||
|
const char *name = xpackage->Attribute("name");
|
||||||
|
const char *platform = xpackage->Attribute("platform");
|
||||||
|
const char *version = xpackage->Attribute("version");
|
||||||
|
if (name != NULL && platform != NULL && version != NULL &&
|
||||||
|
package_name == name &&
|
||||||
|
package_platform == platform &&
|
||||||
|
package_version == version) {
|
||||||
|
// Here's the matching package definition.
|
||||||
|
desc_file.load_xml(xpackage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
xpackage = xpackage->NextSiblingElement("package");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couldn't find the named package.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstanceManager::get_unique_id
|
// Function: P3DInstanceManager::get_unique_id
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -384,6 +477,38 @@ delete_global_ptr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DInstanceManager::copy_file
|
||||||
|
// Access: Private
|
||||||
|
// Description: Copies the data in the file named by from_filename
|
||||||
|
// into the file named by to_filename.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool P3DInstanceManager::
|
||||||
|
copy_file(const string &from_filename, const string &to_filename) {
|
||||||
|
ifstream in(from_filename.c_str(), ios::in | ios::binary);
|
||||||
|
ofstream out(to_filename.c_str(), ios::out | ios::binary);
|
||||||
|
|
||||||
|
static const size_t buffer_size = 4096;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
|
||||||
|
in.read(buffer, buffer_size);
|
||||||
|
size_t count = in.gcount();
|
||||||
|
while (count != 0) {
|
||||||
|
out.write(buffer, count);
|
||||||
|
if (out.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in.read(buffer, buffer_size);
|
||||||
|
count = in.gcount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in.eof()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstanceManager::nt_thread_run
|
// Function: P3DInstanceManager::nt_thread_run
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
class P3DInstance;
|
class P3DInstance;
|
||||||
class P3DSession;
|
class P3DSession;
|
||||||
class P3DPackage;
|
class P3DPackage;
|
||||||
|
class FileSpec;
|
||||||
|
class TiXmlElement;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : P3DInstanceManager
|
// Class : P3DInstanceManager
|
||||||
@ -37,7 +39,7 @@ private:
|
|||||||
~P3DInstanceManager();
|
~P3DInstanceManager();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool initialize();
|
bool initialize(const string &contents_xml_filename);
|
||||||
|
|
||||||
inline bool is_initialized() const;
|
inline bool is_initialized() const;
|
||||||
|
|
||||||
@ -45,11 +47,15 @@ public:
|
|||||||
inline const string &get_download_url() const;
|
inline const string &get_download_url() const;
|
||||||
inline const string &get_platform() const;
|
inline const string &get_platform() const;
|
||||||
|
|
||||||
P3DInstance *
|
inline bool has_contents_file() const;
|
||||||
create_instance(P3D_request_ready_func *func, void *user_data);
|
bool read_contents_file(const string &contents_filename);
|
||||||
|
|
||||||
bool start_instance(P3DInstance *inst, const string &p3d_filename,
|
P3DInstance *
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
create_instance(P3D_request_ready_func *func,
|
||||||
|
const P3D_token tokens[], size_t num_tokens,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
bool start_instance(P3DInstance *inst, const string &p3d_filename);
|
||||||
void finish_instance(P3DInstance *inst);
|
void finish_instance(P3DInstance *inst);
|
||||||
|
|
||||||
P3DInstance *validate_instance(P3D_instance *instance);
|
P3DInstance *validate_instance(P3D_instance *instance);
|
||||||
@ -60,6 +66,9 @@ public:
|
|||||||
P3DPackage *get_package(const string &package_name,
|
P3DPackage *get_package(const string &package_name,
|
||||||
const string &package_version,
|
const string &package_version,
|
||||||
const string &package_display_name);
|
const string &package_display_name);
|
||||||
|
bool get_package_desc_file(FileSpec &desc_file,
|
||||||
|
const string &package_name,
|
||||||
|
const string &package_version);
|
||||||
|
|
||||||
inline int get_num_instances() const;
|
inline int get_num_instances() const;
|
||||||
|
|
||||||
@ -75,6 +84,9 @@ public:
|
|||||||
static P3DInstanceManager *get_global_ptr();
|
static P3DInstanceManager *get_global_ptr();
|
||||||
static void delete_global_ptr();
|
static void delete_global_ptr();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool copy_file(const string &from_filename, const string &to_filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The notify thread. This thread runs only for the purpose of
|
// The notify thread. This thread runs only for the purpose of
|
||||||
// generating asynchronous notifications of requests, to callers who
|
// generating asynchronous notifications of requests, to callers who
|
||||||
@ -88,6 +100,8 @@ private:
|
|||||||
string _download_url;
|
string _download_url;
|
||||||
string _platform;
|
string _platform;
|
||||||
|
|
||||||
|
TiXmlElement *_xcontents;
|
||||||
|
|
||||||
P3D_object *_undefined_object;
|
P3D_object *_undefined_object;
|
||||||
P3D_object *_none_object;
|
P3D_object *_none_object;
|
||||||
P3D_object *_true_object;
|
P3D_object *_true_object;
|
||||||
|
@ -35,23 +35,25 @@ static const double extract_portion = 0.05;
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DPackage::
|
P3DPackage::
|
||||||
P3DPackage(const string &package_name, const string &package_version,
|
P3DPackage(const string &package_name,
|
||||||
const string &package_platform,
|
const string &package_platform,
|
||||||
|
const string &package_version,
|
||||||
const string &package_display_name) :
|
const string &package_display_name) :
|
||||||
_package_name(package_name),
|
_package_name(package_name),
|
||||||
_package_version(package_version),
|
|
||||||
_package_platform(package_platform),
|
_package_platform(package_platform),
|
||||||
|
_package_version(package_version),
|
||||||
_package_display_name(package_display_name)
|
_package_display_name(package_display_name)
|
||||||
{
|
{
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
|
||||||
_package_fullname = _package_name + "_" + _package_version;
|
_package_fullname = _package_name;
|
||||||
_package_dir = inst_mgr->get_root_dir() + string("/") + _package_name;
|
_package_dir = inst_mgr->get_root_dir() + string("/") + _package_name;
|
||||||
|
|
||||||
if (!_package_platform.empty()) {
|
if (!_package_platform.empty()) {
|
||||||
_package_fullname += "_" + _package_platform;
|
_package_fullname += string("_") + _package_platform;
|
||||||
_package_dir += "/" + _package_platform;
|
_package_dir += string("/") + _package_platform;
|
||||||
}
|
}
|
||||||
|
_package_fullname += string("_") + _package_version;
|
||||||
|
_package_dir += string("/") + _package_version;
|
||||||
|
|
||||||
_ready = false;
|
_ready = false;
|
||||||
_failed = false;
|
_failed = false;
|
||||||
@ -59,7 +61,6 @@ P3DPackage(const string &package_name, const string &package_version,
|
|||||||
_partial_download = false;
|
_partial_download = false;
|
||||||
|
|
||||||
// Ensure the package directory exists; create it if it does not.
|
// Ensure the package directory exists; create it if it does not.
|
||||||
_package_dir += string("/") + _package_version;
|
|
||||||
mkdir_complete(_package_dir, nout);
|
mkdir_complete(_package_dir, nout);
|
||||||
|
|
||||||
_desc_file_basename = _package_fullname + ".xml";
|
_desc_file_basename = _package_fullname + ".xml";
|
||||||
@ -186,20 +187,68 @@ begin_download() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should check the desc file for updates with the server.
|
download_contents_file();
|
||||||
// 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.
|
// Function: P3DPackage::download_contents_file
|
||||||
/*
|
// Access: Private
|
||||||
// Load the desc file, if it exists.
|
// Description: Starts downloading the root-level contents.xml file.
|
||||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
// This is only done for the first package, and only if
|
||||||
if (!doc.LoadFile()) {
|
// the instance manager doesn't have the file already.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DPackage::
|
||||||
|
download_contents_file() {
|
||||||
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
|
||||||
|
if (inst_mgr->has_contents_file()) {
|
||||||
|
// We've already got a contents.xml file; go straight to the
|
||||||
|
// package desc file.
|
||||||
download_desc_file();
|
download_desc_file();
|
||||||
} else {
|
return;
|
||||||
got_desc_file(&doc, false);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
string url = inst_mgr->get_download_url();
|
||||||
|
url += "contents.xml";
|
||||||
|
|
||||||
|
// Download contents.xml to a temporary filename first, in case
|
||||||
|
// multiple packages are downloading it simultaneously.
|
||||||
|
_contents_file_pathname = tempnam(NULL, "p3d_");
|
||||||
|
|
||||||
|
cerr << "starting contents download\n";
|
||||||
|
start_download(DT_contents_file, url, _contents_file_pathname, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPackage::contents_file_download_finished
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called when the desc file has been fully downloaded.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DPackage::
|
||||||
|
contents_file_download_finished(bool success) {
|
||||||
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
cerr << "done contents download: " << success
|
||||||
|
<< ", has_contents = " << inst_mgr->has_contents_file()
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
if (!inst_mgr->has_contents_file()) {
|
||||||
|
if (!success || !inst_mgr->read_contents_file(_contents_file_pathname)) {
|
||||||
|
nout << "Couldn't read " << _contents_file_pathname << "\n";
|
||||||
|
|
||||||
|
// Maybe we can read an already-downloaded contents.xml file.
|
||||||
|
string standard_filename = inst_mgr->get_root_dir() + "/contents.xml";
|
||||||
|
if (!inst_mgr->read_contents_file(standard_filename)) {
|
||||||
|
// Couldn't even read that. Fail.
|
||||||
|
report_done(false);
|
||||||
|
unlink(_contents_file_pathname.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The file is correctly installed by now; we can remove the
|
||||||
|
// temporary file.
|
||||||
|
unlink(_contents_file_pathname.c_str());
|
||||||
|
|
||||||
download_desc_file();
|
download_desc_file();
|
||||||
}
|
}
|
||||||
@ -212,12 +261,40 @@ begin_download() {
|
|||||||
void P3DPackage::
|
void P3DPackage::
|
||||||
download_desc_file() {
|
download_desc_file() {
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
|
|
||||||
|
// Attempt to check the desc file for freshness. If it already
|
||||||
|
// exists, and is consistent with the server contents file, we don't
|
||||||
|
// need to re-download it.
|
||||||
|
string root_dir = inst_mgr->get_root_dir();
|
||||||
|
FileSpec desc_file;
|
||||||
|
if (!inst_mgr->get_package_desc_file(desc_file, _package_name, _package_version)) {
|
||||||
|
nout << "Couldn't find package " << _package_fullname
|
||||||
|
<< " in contents file.\n";
|
||||||
|
|
||||||
|
} else if (desc_file.get_pathname(root_dir) != _desc_file_pathname) {
|
||||||
|
nout << "Wrong pathname for desc file: "
|
||||||
|
<< desc_file.get_pathname(root_dir)
|
||||||
|
<< " instead of " << _desc_file_pathname << "\n";
|
||||||
|
|
||||||
|
} else if (!desc_file.quick_verify(root_dir)) {
|
||||||
|
nout << _desc_file_pathname << " is stale.\n";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The desc file is current. Attempt to read it.
|
||||||
|
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||||
|
if (doc.LoadFile()) {
|
||||||
|
got_desc_file(&doc, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The desc file is not current. Go download it.
|
||||||
string url = inst_mgr->get_download_url();
|
string url = inst_mgr->get_download_url();
|
||||||
url += _package_name + "/" + _package_version;
|
url += _package_name;
|
||||||
if (!_package_platform.empty()) {
|
if (!_package_platform.empty()) {
|
||||||
url += "/" + _package_platform;
|
url += "/" + _package_platform;
|
||||||
}
|
}
|
||||||
|
url += "/" + _package_version;
|
||||||
url += "/" + _desc_file_basename;
|
url += "/" + _desc_file_basename;
|
||||||
|
|
||||||
start_download(DT_desc_file, url, _desc_file_pathname, false);
|
start_download(DT_desc_file, url, _desc_file_pathname, false);
|
||||||
@ -321,11 +398,11 @@ void P3DPackage::
|
|||||||
download_compressed_archive(bool allow_partial) {
|
download_compressed_archive(bool allow_partial) {
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
string url = inst_mgr->get_download_url();
|
string url = inst_mgr->get_download_url();
|
||||||
url += _package_name + "/" + _package_version;
|
url += _package_name;
|
||||||
if (!_package_platform.empty()) {
|
if (!_package_platform.empty()) {
|
||||||
url += "/" + _package_platform;
|
url += "/" + _package_platform;
|
||||||
}
|
}
|
||||||
|
url += "/" + _package_version;
|
||||||
url += "/" + _compressed_archive.get_filename();
|
url += "/" + _compressed_archive.get_filename();
|
||||||
|
|
||||||
string target_pathname = _package_dir + "/" + _compressed_archive.get_filename();
|
string target_pathname = _package_dir + "/" + _compressed_archive.get_filename();
|
||||||
@ -667,6 +744,10 @@ download_finished(bool success) {
|
|||||||
_package->_active_download = NULL;
|
_package->_active_download = NULL;
|
||||||
|
|
||||||
switch (_dtype) {
|
switch (_dtype) {
|
||||||
|
case DT_contents_file:
|
||||||
|
_package->contents_file_download_finished(success);
|
||||||
|
break;
|
||||||
|
|
||||||
case DT_desc_file:
|
case DT_desc_file:
|
||||||
_package->desc_file_download_finished(success);
|
_package->desc_file_download_finished(success);
|
||||||
break;
|
break;
|
||||||
|
@ -36,8 +36,9 @@ class P3DInstance;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DPackage {
|
class P3DPackage {
|
||||||
public:
|
public:
|
||||||
P3DPackage(const string &package_name, const string &package_version,
|
P3DPackage(const string &package_name,
|
||||||
const string &package_platform,
|
const string &package_platform,
|
||||||
|
const string &package_version,
|
||||||
const string &package_display_name);
|
const string &package_display_name);
|
||||||
~P3DPackage();
|
~P3DPackage();
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
enum DownloadType {
|
enum DownloadType {
|
||||||
|
DT_contents_file,
|
||||||
DT_desc_file,
|
DT_desc_file,
|
||||||
DT_compressed_archive
|
DT_compressed_archive
|
||||||
};
|
};
|
||||||
@ -81,6 +83,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void begin_download();
|
void begin_download();
|
||||||
|
void download_contents_file();
|
||||||
|
void contents_file_download_finished(bool success);
|
||||||
|
|
||||||
void download_desc_file();
|
void download_desc_file();
|
||||||
void desc_file_download_finished(bool success);
|
void desc_file_download_finished(bool success);
|
||||||
void got_desc_file(TiXmlDocument *doc, bool freshly_downloaded);
|
void got_desc_file(TiXmlDocument *doc, bool freshly_downloaded);
|
||||||
@ -105,6 +110,8 @@ private:
|
|||||||
string _package_fullname;
|
string _package_fullname;
|
||||||
string _package_dir;
|
string _package_dir;
|
||||||
|
|
||||||
|
string _contents_file_pathname;
|
||||||
|
|
||||||
string _desc_file_basename;
|
string _desc_file_basename;
|
||||||
string _desc_file_pathname;
|
string _desc_file_pathname;
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
void P3DWinSplashWindow::
|
void P3DWinSplashWindow::
|
||||||
set_image_filename(const string &image_filename,
|
set_image_filename(const string &image_filename,
|
||||||
bool image_filename_temp) {
|
bool image_filename_temp) {
|
||||||
|
nout << "image_filename = " << image_filename << ", thread_id = " << _thread_id << "\n";
|
||||||
ACQUIRE_LOCK(_install_lock);
|
ACQUIRE_LOCK(_install_lock);
|
||||||
if (_image_filename != image_filename) {
|
if (_image_filename != image_filename) {
|
||||||
_image_filename = image_filename;
|
_image_filename = image_filename;
|
||||||
@ -261,34 +262,33 @@ thread_run() {
|
|||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
|
||||||
if (_got_install) {
|
ACQUIRE_LOCK(_install_lock);
|
||||||
ACQUIRE_LOCK(_install_lock);
|
bool got_install = _got_install;
|
||||||
double install_progress = _install_progress;
|
double install_progress = _install_progress;
|
||||||
if (_image_filename_changed) {
|
if (_image_filename_changed) {
|
||||||
update_image_filename(_image_filename, _image_filename_temp);
|
update_image_filename(_image_filename, _image_filename_temp);
|
||||||
}
|
}
|
||||||
_image_filename_changed = false;
|
_image_filename_changed = false;
|
||||||
if (_install_label_changed && _progress_bar != NULL) {
|
if (_install_label_changed && _progress_bar != NULL) {
|
||||||
update_install_label(_install_label);
|
update_install_label(_install_label);
|
||||||
}
|
}
|
||||||
_install_label_changed = false;
|
_install_label_changed = false;
|
||||||
RELEASE_LOCK(_install_lock);
|
RELEASE_LOCK(_install_lock);
|
||||||
|
|
||||||
if (install_progress != last_progress) {
|
if (got_install && install_progress != last_progress) {
|
||||||
if (_progress_bar == NULL) {
|
if (_progress_bar == NULL) {
|
||||||
// Is it time to create the progress bar?
|
// Is it time to create the progress bar?
|
||||||
int now = GetTickCount();
|
int now = GetTickCount();
|
||||||
if (now - _loop_started > 2000) {
|
if (now - _loop_started > 2000) {
|
||||||
make_progress_bar();
|
make_progress_bar();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Update the progress bar. We do this only within the
|
|
||||||
// thread, to ensure we don't get a race condition when
|
|
||||||
// starting or closing the thread.
|
|
||||||
SendMessage(_progress_bar, PBM_SETPOS, (int)(install_progress * 100.0), 0);
|
|
||||||
|
|
||||||
last_progress = install_progress;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Update the progress bar. We do this only within the
|
||||||
|
// thread, to ensure we don't get a race condition when
|
||||||
|
// starting or closing the thread.
|
||||||
|
SendMessage(_progress_bar, PBM_SETPOS, (int)(install_progress * 100.0), 0);
|
||||||
|
|
||||||
|
last_progress = install_progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "p3d_plugin_common.h"
|
#include "p3d_plugin_common.h"
|
||||||
|
#include "p3d_plugin_config.h"
|
||||||
#include "p3dInstanceManager.h"
|
#include "p3dInstanceManager.h"
|
||||||
#include "p3dInstance.h"
|
#include "p3dInstance.h"
|
||||||
#include "p3dWindowParams.h"
|
#include "p3dWindowParams.h"
|
||||||
@ -37,7 +38,7 @@ ostream *nout_stream;
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
P3D_initialize(int api_version, const char *output_filename) {
|
P3D_initialize(int api_version, const char *contents_filename) {
|
||||||
if (api_version != P3D_API_VERSION) {
|
if (api_version != P3D_API_VERSION) {
|
||||||
// Can't accept an incompatible version.
|
// Can't accept an incompatible version.
|
||||||
return false;
|
return false;
|
||||||
@ -49,21 +50,40 @@ P3D_initialize(int api_version, const char *output_filename) {
|
|||||||
}
|
}
|
||||||
ACQUIRE_LOCK(_api_lock);
|
ACQUIRE_LOCK(_api_lock);
|
||||||
|
|
||||||
plugin_output_filename = string();
|
if (contents_filename == NULL){
|
||||||
if (output_filename != NULL) {
|
contents_filename = "";
|
||||||
plugin_output_filename = output_filename;
|
|
||||||
}
|
}
|
||||||
nout_stream = &cerr;
|
|
||||||
if (!plugin_output_filename.empty()) {
|
#ifdef P3D_PLUGIN_LOGFILE2
|
||||||
logfile.open(plugin_output_filename.c_str(), ios::out | ios::trunc);
|
string logfilename = P3D_PLUGIN_LOGFILE2;
|
||||||
if (logfile) {
|
#else
|
||||||
logfile.setf(ios::unitbuf);
|
string logfilename;
|
||||||
nout_stream = &logfile;
|
#endif // P3D_PLUGIN_LOGFILE2
|
||||||
|
|
||||||
|
if (logfilename.empty()) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
static const size_t buffer_size = 4096;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
if (GetTempPath(buffer_size, buffer) != 0) {
|
||||||
|
logfilename = buffer;
|
||||||
|
logfilename += "panda3d.2.log";
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
logfilename = "/tmp/panda3d.2.log";
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "logfile: " << logfilename << "\n";
|
||||||
|
|
||||||
|
nout_stream = &cerr;
|
||||||
|
logfile.open(logfilename.c_str(), ios::out | ios::trunc);
|
||||||
|
if (logfile) {
|
||||||
|
logfile.setf(ios::unitbuf);
|
||||||
|
nout_stream = &logfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
bool result = inst_mgr->initialize();
|
bool result = inst_mgr->initialize(contents_filename);
|
||||||
RELEASE_LOCK(_api_lock);
|
RELEASE_LOCK(_api_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -74,18 +94,21 @@ P3D_finalize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
P3D_instance *
|
P3D_instance *
|
||||||
P3D_new_instance(P3D_request_ready_func *func, void *user_data) {
|
P3D_new_instance(P3D_request_ready_func *func,
|
||||||
|
const P3D_token tokens[], size_t num_tokens,
|
||||||
|
void *user_data) {
|
||||||
|
nout << "new_instance\n";
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
ACQUIRE_LOCK(_api_lock);
|
ACQUIRE_LOCK(_api_lock);
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
P3DInstance *result = inst_mgr->create_instance(func, user_data);
|
P3DInstance *result = inst_mgr->create_instance(func, tokens, num_tokens, user_data);
|
||||||
RELEASE_LOCK(_api_lock);
|
RELEASE_LOCK(_api_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
P3D_instance_start(P3D_instance *instance, const char *p3d_filename,
|
P3D_instance_start(P3D_instance *instance, const char *p3d_filename) {
|
||||||
const P3D_token tokens[], size_t num_tokens) {
|
nout << "instance_start\n";
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
if (p3d_filename == NULL) {
|
if (p3d_filename == NULL) {
|
||||||
p3d_filename = "";
|
p3d_filename = "";
|
||||||
@ -95,7 +118,7 @@ P3D_instance_start(P3D_instance *instance, const char *p3d_filename,
|
|||||||
P3DInstance *inst = inst_mgr->validate_instance(instance);
|
P3DInstance *inst = inst_mgr->validate_instance(instance);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (inst != NULL) {
|
if (inst != NULL) {
|
||||||
result = inst_mgr->start_instance(inst, p3d_filename, tokens, num_tokens);
|
result = inst_mgr->start_instance(inst, p3d_filename);
|
||||||
}
|
}
|
||||||
RELEASE_LOCK(_api_lock);
|
RELEASE_LOCK(_api_lock);
|
||||||
return result;
|
return result;
|
||||||
@ -119,6 +142,7 @@ P3D_instance_setup_window(P3D_instance *instance,
|
|||||||
int win_x, int win_y,
|
int win_x, int win_y,
|
||||||
int win_width, int win_height,
|
int win_width, int win_height,
|
||||||
P3D_window_handle parent_window) {
|
P3D_window_handle parent_window) {
|
||||||
|
nout << "setup_window\n";
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
P3DWindowParams wparams(window_type, win_x, win_y,
|
P3DWindowParams wparams(window_type, win_x, win_y,
|
||||||
win_width, win_height, parent_window);
|
win_width, win_height, parent_window);
|
||||||
|
@ -79,7 +79,7 @@ extern "C" {
|
|||||||
(below). This number will be incremented whenever there are changes
|
(below). This number will be incremented whenever there are changes
|
||||||
to any of the interface specifications defined in this header
|
to any of the interface specifications defined in this header
|
||||||
file. */
|
file. */
|
||||||
#define P3D_API_VERSION 4
|
#define P3D_API_VERSION 5
|
||||||
|
|
||||||
/************************ GLOBAL FUNCTIONS **************************/
|
/************************ GLOBAL FUNCTIONS **************************/
|
||||||
|
|
||||||
@ -91,17 +91,16 @@ extern "C" {
|
|||||||
the DLL can verify that it has been built with the same version of
|
the DLL can verify that it has been built with the same version of
|
||||||
the API as the host.
|
the API as the host.
|
||||||
|
|
||||||
The output_filename is usually NULL, but if you put a filename
|
The contents_filename, if not NULL or empty, names a contents.xml
|
||||||
here, it will be used as the log file for the output from the core
|
file that has already been downloaded and verified from the server.
|
||||||
API. This is useful for debugging, particularly when running
|
If this is NULL, a new file will be downloaded as needed.
|
||||||
within a browser that squelches stderr.
|
|
||||||
|
|
||||||
This function returns true if the core API is valid and uses a
|
This function returns true if the core API is valid and uses a
|
||||||
compatible API, false otherwise. If it returns false, the host
|
compatible API, false otherwise. If it returns false, the host
|
||||||
should not call any more functions in this API, and should
|
should not call any more functions in this API, and should
|
||||||
immediately unload the DLL and (if possible) download a new one. */
|
immediately unload the DLL and (if possible) download a new one. */
|
||||||
typedef bool
|
typedef bool
|
||||||
P3D_initialize_func(int api_version, const char *output_filename);
|
P3D_initialize_func(int api_version, const char *contents_filename);
|
||||||
|
|
||||||
/* This function should be called to unload the core API. It will
|
/* This function should be called to unload the core API. It will
|
||||||
release all internally-allocated memory and return the core API to
|
release all internally-allocated memory and return the core API to
|
||||||
@ -210,16 +209,25 @@ typedef struct {
|
|||||||
|
|
||||||
/* This function creates a new Panda3D instance.
|
/* This function creates a new Panda3D instance.
|
||||||
|
|
||||||
|
For tokens, pass an array of P3D_token elements (above), which
|
||||||
|
correspond to the user-supplied keyword/value pairs that may appear
|
||||||
|
in the embed token within the HTML syntax; the host is responsible
|
||||||
|
for allocating this array, and for deallocating it after this call
|
||||||
|
(the core API will make its own copy of the array). The tokens are
|
||||||
|
passed to the application, who is free to decide how to interpret
|
||||||
|
them; they have no meaning at the system level.
|
||||||
|
|
||||||
The user_data pointer is any arbitrary pointer value; it will be
|
The user_data pointer is any arbitrary pointer value; it will be
|
||||||
copied into the _user_data member of the new P3D_instance object.
|
copied into the _user_data member of the new P3D_instance object.
|
||||||
This pointer is intended for the host to use to store private data
|
This pointer is intended for the host to use to store private data
|
||||||
associated with each instance; the core API will not do anything with
|
associated with each instance; the core API will not do anything with
|
||||||
this data.
|
this data.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef P3D_instance *
|
typedef P3D_instance *
|
||||||
P3D_new_instance_func(P3D_request_ready_func *func, void *user_data);
|
P3D_new_instance_func(P3D_request_ready_func *func,
|
||||||
|
const P3D_token tokens[], size_t num_tokens,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
/* This function should be called at some point after
|
/* This function should be called at some point after
|
||||||
P3D_new_instance(); it actually starts the instance running.
|
P3D_new_instance(); it actually starts the instance running.
|
||||||
@ -230,29 +238,9 @@ P3D_new_instance_func(P3D_request_ready_func *func, void *user_data);
|
|||||||
instance. If this is empty or NULL, the "src" token (below) will
|
instance. If this is empty or NULL, the "src" token (below) will
|
||||||
be downloaded instead.
|
be downloaded instead.
|
||||||
|
|
||||||
For tokens, pass an array of P3D_token elements (above), which
|
|
||||||
correspond to the user-supplied keyword/value pairs that may appear
|
|
||||||
in the embed token within the HTML syntax; the host is responsible
|
|
||||||
for allocating this array, and for deallocating it after this call
|
|
||||||
(the core API will make its own copy of the array).
|
|
||||||
|
|
||||||
Most tokens are implemented by the application and are undefined at
|
|
||||||
the system level. However, two tokens in particular are
|
|
||||||
system-defined:
|
|
||||||
|
|
||||||
"src" : names a URL that will be loaded for the contents of the
|
|
||||||
p3d file, if p3d_filename is empty or NULL.
|
|
||||||
|
|
||||||
"output_filename" : names a file to create on disk which contains
|
|
||||||
the console output from the application. This may be useful in
|
|
||||||
debugging. If this is omitted, or an empty string, the console
|
|
||||||
output is written to the standard error output, which may be
|
|
||||||
NULL on a gui application.
|
|
||||||
|
|
||||||
The return value is true on success, false on failure. */
|
The return value is true on success, false on failure. */
|
||||||
typedef bool
|
typedef bool
|
||||||
P3D_instance_start_func(P3D_instance *instance, const char *p3d_filename,
|
P3D_instance_start_func(P3D_instance *instance, const char *p3d_filename);
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
|
||||||
|
|
||||||
|
|
||||||
/* Call this function to interrupt a particular instance and stop it
|
/* Call this function to interrupt a particular instance and stop it
|
||||||
|
@ -51,6 +51,8 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
|
|||||||
_tokens.push_back(token);
|
_tokens.push_back(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_root_dir = find_root_dir();
|
||||||
|
|
||||||
_started_instance_data = false;
|
_started_instance_data = false;
|
||||||
_got_instance_data = false;
|
_got_instance_data = false;
|
||||||
_got_window = false;
|
_got_window = false;
|
||||||
@ -313,7 +315,15 @@ url_notify(const char *url, NPReason reason, void *notifyData) {
|
|||||||
case PPDownloadRequest::RT_contents_file:
|
case PPDownloadRequest::RT_contents_file:
|
||||||
if (reason != NPRES_DONE) {
|
if (reason != NPRES_DONE) {
|
||||||
nout << "Failure downloading " << url << "\n";
|
nout << "Failure downloading " << url << "\n";
|
||||||
// TODO: fail
|
|
||||||
|
// Couldn't download a fresh contents.xml for some reason. If
|
||||||
|
// there's an outstanding contents.xml file on disk, try to load
|
||||||
|
// that one as a fallback.
|
||||||
|
string contents_filename = _root_dir + "/contents.xml";
|
||||||
|
if (!read_contents_file(contents_filename)) {
|
||||||
|
nout << "Unable to read contents file " << contents_filename << "\n";
|
||||||
|
// TODO: fail
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -361,11 +371,11 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
// Looks like we've converted it successfully.
|
// Looks like we've converted it successfully.
|
||||||
filename = fname2;
|
filename = fname2;
|
||||||
|
|
||||||
// Here's another temporary hack. In addition to the weird
|
// Here's another crazy hack. In addition to the weird filename
|
||||||
// filename format, the file that Safari tells us about appears
|
// format, the file that Safari tells us about appears to be a
|
||||||
// to be a temporary file that Safari's about to delete. In
|
// temporary file that Safari's about to delete. In order to
|
||||||
// order to protect ourselves from this, we need to temporarily
|
// protect ourselves from this, we need to temporarily copy the
|
||||||
// copy the file somewhere else.
|
// file somewhere else.
|
||||||
char *name = tempnam(NULL, "p3d_");
|
char *name = tempnam(NULL, "p3d_");
|
||||||
|
|
||||||
// We prefer just making a hard link; it's quick and easy.
|
// We prefer just making a hard link; it's quick and easy.
|
||||||
@ -373,19 +383,7 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
// But sometimes the hard link might fail, particularly if these
|
// But sometimes the hard link might fail, particularly if these
|
||||||
// are two different file systems. In this case we have to open
|
// are two different file systems. In this case we have to open
|
||||||
// the files and copy the data by hand.
|
// the files and copy the data by hand.
|
||||||
ifstream in(filename.c_str(), ios::in | ios::binary);
|
copy_file(filename, name);
|
||||||
ofstream out(name, ios::out | ios::binary);
|
|
||||||
|
|
||||||
static const size_t buffer_size = 4096;
|
|
||||||
char buffer[buffer_size];
|
|
||||||
|
|
||||||
in.read(buffer, buffer_size);
|
|
||||||
size_t count = in.gcount();
|
|
||||||
while (count != 0) {
|
|
||||||
out.write(buffer, count);
|
|
||||||
in.read(buffer, buffer_size);
|
|
||||||
count = in.gcount();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = name;
|
filename = name;
|
||||||
@ -439,7 +437,7 @@ handle_request(P3D_request *request) {
|
|||||||
if (strcmp(request->_request._notify._message, "onwindowopen") == 0) {
|
if (strcmp(request->_request._notify._message, "onwindowopen") == 0) {
|
||||||
_python_window_open = true;
|
_python_window_open = true;
|
||||||
if (_got_window) {
|
if (_got_window) {
|
||||||
NPRect rect = { 0, 0, _window.height, _window.width };
|
NPRect rect = { 0, 0, (unsigned short)_window.height, (unsigned short)_window.width };
|
||||||
browser->invalidaterect(_npp_instance, &rect);
|
browser->invalidaterect(_npp_instance, &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,7 +445,7 @@ handle_request(P3D_request *request) {
|
|||||||
|
|
||||||
case P3D_RT_refresh:
|
case P3D_RT_refresh:
|
||||||
if (_got_window) {
|
if (_got_window) {
|
||||||
NPRect rect = { 0, 0, _window.height, _window.width };
|
NPRect rect = { 0, 0, (unsigned short)_window.height, (unsigned short)_window.width };
|
||||||
browser->invalidaterect(_npp_instance, &rect);
|
browser->invalidaterect(_npp_instance, &rect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -700,8 +698,8 @@ start_download(const string &url, PPDownloadRequest *req) {
|
|||||||
// DLL downloading, if necessary.
|
// DLL downloading, if necessary.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool PPInstance::
|
bool PPInstance::
|
||||||
read_contents_file(const string &filename) {
|
read_contents_file(const string &contents_filename) {
|
||||||
TiXmlDocument doc(filename.c_str());
|
TiXmlDocument doc(contents_filename.c_str());
|
||||||
if (!doc.LoadFile()) {
|
if (!doc.LoadFile()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -765,9 +763,23 @@ downloaded_file(PPDownloadRequest *req, const string &filename) {
|
|||||||
case PPDownloadRequest::RT_contents_file:
|
case PPDownloadRequest::RT_contents_file:
|
||||||
// Now we have the contents.xml file. Read this to get the
|
// Now we have the contents.xml file. Read this to get the
|
||||||
// filename and md5 hash of our core API DLL.
|
// filename and md5 hash of our core API DLL.
|
||||||
if (!read_contents_file(filename)) {
|
if (read_contents_file(filename)) {
|
||||||
nout << "Unable to read contents file\n";
|
// Successfully read. Copy it into its normal place.
|
||||||
// TODO: fail
|
string contents_filename = _root_dir + "/contents.xml";
|
||||||
|
copy_file(filename, contents_filename);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Error reading the contents.xml file, or in loading the core
|
||||||
|
// API that it references.
|
||||||
|
nout << "Unable to read contents file " << filename << "\n";
|
||||||
|
|
||||||
|
// If there's an outstanding contents.xml file on disk, try to
|
||||||
|
// load that one as a fallback.
|
||||||
|
string contents_filename = _root_dir + "/contents.xml";
|
||||||
|
if (!read_contents_file(contents_filename)) {
|
||||||
|
nout << "Unable to read contents file " << contents_filename << "\n";
|
||||||
|
// TODO: fail
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -782,7 +794,10 @@ downloaded_file(PPDownloadRequest *req, const string &filename) {
|
|||||||
// launch the instance.
|
// launch the instance.
|
||||||
_got_instance_data = true;
|
_got_instance_data = true;
|
||||||
_p3d_filename = filename;
|
_p3d_filename = filename;
|
||||||
create_instance();
|
|
||||||
|
if (_p3d_inst != NULL) {
|
||||||
|
P3D_instance_start(_p3d_inst, _p3d_filename.c_str());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_user:
|
case PPDownloadRequest::RT_user:
|
||||||
@ -821,8 +836,6 @@ void PPInstance::
|
|||||||
get_core_api(TiXmlElement *xpackage) {
|
get_core_api(TiXmlElement *xpackage) {
|
||||||
_core_api_dll.load_xml(xpackage);
|
_core_api_dll.load_xml(xpackage);
|
||||||
|
|
||||||
_root_dir = find_root_dir();
|
|
||||||
|
|
||||||
if (_core_api_dll.quick_verify(_root_dir)) {
|
if (_core_api_dll.quick_verify(_root_dir)) {
|
||||||
// The DLL file is good. Just load it.
|
// The DLL file is good. Just load it.
|
||||||
do_load_plugin();
|
do_load_plugin();
|
||||||
@ -919,7 +932,7 @@ do_load_plugin() {
|
|||||||
}
|
}
|
||||||
#endif // P3D_PLUGIN_P3D_PLUGIN
|
#endif // P3D_PLUGIN_P3D_PLUGIN
|
||||||
|
|
||||||
if (!load_plugin(pathname)) {
|
if (!load_plugin(pathname, "")) {
|
||||||
nout << "Unable to launch core API in " << pathname << "\n";
|
nout << "Unable to launch core API in " << pathname << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -944,12 +957,11 @@ create_instance() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_got_instance_data) {
|
P3D_token *tokens = NULL;
|
||||||
// No instance data yet.
|
if (!_tokens.empty()) {
|
||||||
return;
|
tokens = &_tokens[0];
|
||||||
}
|
}
|
||||||
|
_p3d_inst = P3D_new_instance(request_ready, tokens, _tokens.size(), this);
|
||||||
_p3d_inst = P3D_new_instance(request_ready, this);
|
|
||||||
|
|
||||||
if (_p3d_inst != NULL) {
|
if (_p3d_inst != NULL) {
|
||||||
// Now get the browser's window object, to pass to the plugin.
|
// Now get the browser's window object, to pass to the plugin.
|
||||||
@ -971,11 +983,7 @@ create_instance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_got_instance_data) {
|
if (_got_instance_data) {
|
||||||
P3D_token *tokens = NULL;
|
P3D_instance_start(_p3d_inst, _p3d_filename.c_str());
|
||||||
if (!_tokens.empty()) {
|
|
||||||
tokens = &_tokens[0];
|
|
||||||
}
|
|
||||||
P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_got_window) {
|
if (_got_window) {
|
||||||
@ -1062,6 +1070,38 @@ send_window() {
|
|||||||
parent_window);
|
parent_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::copy_file
|
||||||
|
// Access: Public
|
||||||
|
// Description: Copies the data in the file named by from_filename
|
||||||
|
// into the file named by to_filename.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PPInstance::
|
||||||
|
copy_file(const string &from_filename, const string &to_filename) {
|
||||||
|
ifstream in(from_filename.c_str(), ios::in | ios::binary);
|
||||||
|
ofstream out(to_filename.c_str(), ios::out | ios::binary);
|
||||||
|
|
||||||
|
static const size_t buffer_size = 4096;
|
||||||
|
char buffer[buffer_size];
|
||||||
|
|
||||||
|
in.read(buffer, buffer_size);
|
||||||
|
size_t count = in.gcount();
|
||||||
|
while (count != 0) {
|
||||||
|
out.write(buffer, count);
|
||||||
|
if (out.fail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in.read(buffer, buffer_size);
|
||||||
|
count = in.gcount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in.eof()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::output_np_variant
|
// Function: PPInstance::output_np_variant
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -71,13 +71,14 @@ private:
|
|||||||
static string get_filename_from_url(const string &url);
|
static string get_filename_from_url(const string &url);
|
||||||
void feed_file(PPDownloadRequest *req, const string &filename);
|
void feed_file(PPDownloadRequest *req, const string &filename);
|
||||||
|
|
||||||
bool read_contents_file(const string &filename);
|
bool read_contents_file(const string &contents_filename);
|
||||||
void get_core_api(TiXmlElement *xpackage);
|
void get_core_api(TiXmlElement *xpackage);
|
||||||
void downloaded_plugin(const string &filename);
|
void downloaded_plugin(const string &filename);
|
||||||
void do_load_plugin();
|
void do_load_plugin();
|
||||||
|
|
||||||
void create_instance();
|
void create_instance();
|
||||||
void send_window();
|
void send_window();
|
||||||
|
bool copy_file(const string &from_filename, const string &to_filename);
|
||||||
|
|
||||||
static void handle_request_loop();
|
static void handle_request_loop();
|
||||||
static void browser_sync_callback(void *);
|
static void browser_sync_callback(void *);
|
||||||
|
@ -286,8 +286,8 @@ run(int argc, char *argv[]) {
|
|||||||
bool Panda3D::
|
bool Panda3D::
|
||||||
get_plugin(const string &root_url, const string &this_platform, bool force_download) {
|
get_plugin(const string &root_url, const string &this_platform, bool force_download) {
|
||||||
// First, look for the existing contents.xml file.
|
// First, look for the existing contents.xml file.
|
||||||
Filename contents = Filename(Filename::from_os_specific(_root_dir), "contents.xml");
|
Filename contents_filename = Filename(Filename::from_os_specific(_root_dir), "contents.xml");
|
||||||
if (!force_download && read_contents_file(contents, root_url, this_platform)) {
|
if (!force_download && read_contents_file(contents_filename, root_url, this_platform)) {
|
||||||
// Got the file, and it's good.
|
// Got the file, and it's good.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -299,13 +299,13 @@ get_plugin(const string &root_url, const string &this_platform, bool force_downl
|
|||||||
|
|
||||||
HTTPClient *http = HTTPClient::get_global_ptr();
|
HTTPClient *http = HTTPClient::get_global_ptr();
|
||||||
PT(HTTPChannel) channel = http->get_document(url);
|
PT(HTTPChannel) channel = http->get_document(url);
|
||||||
contents.make_dir();
|
contents_filename.make_dir();
|
||||||
if (!channel->download_to_file(contents)) {
|
if (!channel->download_to_file(contents_filename)) {
|
||||||
cerr << "Unable to download " << url << "\n";
|
cerr << "Unable to download " << url << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_contents_file(contents, root_url, this_platform);
|
return read_contents_file(contents_filename, root_url, this_platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -316,12 +316,12 @@ get_plugin(const string &root_url, const string &this_platform, bool force_downl
|
|||||||
// possible. Returns true on success, false on failure.
|
// possible. Returns true on success, false on failure.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool Panda3D::
|
bool Panda3D::
|
||||||
read_contents_file(Filename contents, const string &root_url,
|
read_contents_file(Filename contents_filename, const string &root_url,
|
||||||
const string &this_platform) {
|
const string &this_platform) {
|
||||||
ifstream in;
|
ifstream in;
|
||||||
contents.set_text();
|
contents_filename.set_text();
|
||||||
if (!contents.open_read(in)) {
|
if (!contents_filename.open_read(in)) {
|
||||||
cerr << "Couldn't read " << contents.to_os_specific() << "\n";
|
cerr << "Couldn't read " << contents_filename.to_os_specific() << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +336,7 @@ read_contents_file(Filename contents, const string &root_url,
|
|||||||
if (name != NULL && strcmp(name, "coreapi") == 0) {
|
if (name != NULL && strcmp(name, "coreapi") == 0) {
|
||||||
const char *xplatform = xpackage->Attribute("platform");
|
const char *xplatform = xpackage->Attribute("platform");
|
||||||
if (xplatform != NULL && strcmp(xplatform, this_platform.c_str()) == 0) {
|
if (xplatform != NULL && strcmp(xplatform, this_platform.c_str()) == 0) {
|
||||||
return get_core_api(root_url, xpackage);
|
return get_core_api(contents_filename, root_url, xpackage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +359,8 @@ read_contents_file(Filename contents, const string &root_url,
|
|||||||
// if necessary.
|
// if necessary.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool Panda3D::
|
bool Panda3D::
|
||||||
get_core_api(const string &root_url, TiXmlElement *xpackage) {
|
get_core_api(const Filename &contents_filename, const string &root_url,
|
||||||
|
TiXmlElement *xpackage) {
|
||||||
_core_api_dll.load_xml(xpackage);
|
_core_api_dll.load_xml(xpackage);
|
||||||
|
|
||||||
if (!_core_api_dll.quick_verify(_root_dir)) {
|
if (!_core_api_dll.quick_verify(_root_dir)) {
|
||||||
@ -397,7 +398,7 @@ get_core_api(const string &root_url, TiXmlElement *xpackage) {
|
|||||||
}
|
}
|
||||||
#endif // P3D_PLUGIN_P3D_PLUGIN
|
#endif // P3D_PLUGIN_P3D_PLUGIN
|
||||||
|
|
||||||
if (!load_plugin(pathname)) {
|
if (!load_plugin(pathname, contents_filename.to_os_specific())) {
|
||||||
cerr << "Unable to launch core API in " << pathname << "\n" << flush;
|
cerr << "Unable to launch core API in " << pathname << "\n" << flush;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -592,12 +593,12 @@ create_instance(const string &arg, P3D_window_type window_type,
|
|||||||
os_p3d_filename = p3d_filename.to_os_specific();
|
os_p3d_filename = p3d_filename.to_os_specific();
|
||||||
}
|
}
|
||||||
|
|
||||||
P3D_instance *inst = P3D_new_instance(NULL, NULL);
|
P3D_instance *inst = P3D_new_instance(NULL, tokens, num_tokens, NULL);
|
||||||
|
|
||||||
if (inst != NULL) {
|
if (inst != NULL) {
|
||||||
P3D_instance_setup_window
|
P3D_instance_setup_window
|
||||||
(inst, window_type, win_x, win_y, win_width, win_height, parent_window);
|
(inst, window_type, win_x, win_y, win_width, win_height, parent_window);
|
||||||
P3D_instance_start(inst, os_p3d_filename.c_str(), tokens, num_tokens);
|
P3D_instance_start(inst, os_p3d_filename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return inst;
|
return inst;
|
||||||
|
@ -44,9 +44,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool get_plugin(const string &root_url, const string &this_platform,
|
bool get_plugin(const string &root_url, const string &this_platform,
|
||||||
bool force_download);
|
bool force_download);
|
||||||
bool read_contents_file(Filename contents, const string &root_url,
|
bool read_contents_file(Filename contents_filename, const string &root_url,
|
||||||
const string &this_platform);
|
const string &this_platform);
|
||||||
bool get_core_api(const string &root_url, TiXmlElement *xpackage);
|
bool get_core_api(const Filename &contents_filename, const string &root_url,
|
||||||
|
TiXmlElement *xpackage);
|
||||||
void run_getters();
|
void run_getters();
|
||||||
void handle_request(P3D_request *request);
|
void handle_request(P3D_request *request);
|
||||||
void make_parent_window(P3D_window_handle &parent_window,
|
void make_parent_window(P3D_window_handle &parent_window,
|
||||||
|
@ -55,7 +55,7 @@ if sys.platform == 'win32':
|
|||||||
MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific()
|
MSVC = Filename('/c/Program Files/Microsoft Visual Studio .NET 2003/Vc7').toOsSpecific()
|
||||||
else:
|
else:
|
||||||
print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.'
|
print 'Could not locate Microsoft Visual C++ Compiler! Try running from the Visual Studio Command Prompt.'
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if ('WindowsSdkDir' in os.environ):
|
if ('WindowsSdkDir' in os.environ):
|
||||||
PSDK = os.environ['WindowsSdkDir']
|
PSDK = os.environ['WindowsSdkDir']
|
||||||
@ -65,7 +65,7 @@ if sys.platform == 'win32':
|
|||||||
PSDK = os.path.join(MSVC, 'PlatformSDK')
|
PSDK = os.path.join(MSVC, 'PlatformSDK')
|
||||||
else:
|
else:
|
||||||
print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.'
|
print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.'
|
||||||
exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself.
|
# If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself.
|
||||||
if ('MAKEPANDA' in os.environ):
|
if ('MAKEPANDA' in os.environ):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user