mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
super mirror
This commit is contained in:
parent
d2307eb838
commit
508b92005f
@ -102,6 +102,13 @@ class AppRunner(DirectObject):
|
||||
# the instance starts up.
|
||||
self.rootDir = None
|
||||
|
||||
# self.superMirrorUrl, if nonempty, is the "super mirror" URL
|
||||
# that should be contacted first before trying the actual
|
||||
# host. This is primarily used for "downloading" from a
|
||||
# locally-stored Panda3D installation. This is also filled in
|
||||
# when the instance starts up.
|
||||
self.superMirrorUrl = None
|
||||
|
||||
# A list of the Panda3D packages that have been loaded.
|
||||
self.installedPackages = []
|
||||
|
||||
@ -430,11 +437,7 @@ class AppRunner(DirectObject):
|
||||
interactiveConsole = self.interactiveConsole
|
||||
self.interactiveConsole = False
|
||||
|
||||
try:
|
||||
__import__(moduleName)
|
||||
except ImportError:
|
||||
message = "No %s found in application." % (moduleName)
|
||||
raise StandardError, message
|
||||
__import__(moduleName)
|
||||
main = sys.modules[moduleName]
|
||||
if hasattr(main, 'main') and callable(main.main):
|
||||
main.main(self)
|
||||
@ -469,15 +472,17 @@ class AppRunner(DirectObject):
|
||||
needsResponse = False)
|
||||
self.deferredEvals = []
|
||||
|
||||
def setInstanceInfo(self, rootDir):
|
||||
def setInstanceInfo(self, rootDir, superMirrorUrl):
|
||||
""" Called by the browser to set some global information about
|
||||
the instance. """
|
||||
|
||||
# At the present, this only includes rootDir, which is the
|
||||
# root Panda3D install directory on the local machine.
|
||||
|
||||
# rootDir is the root Panda3D install directory on the local
|
||||
# machine.
|
||||
self.rootDir = Filename.fromOsSpecific(rootDir)
|
||||
|
||||
# The "super mirror" URL, generally used only by panda3d.exe.
|
||||
self.superMirrorUrl = superMirrorUrl
|
||||
|
||||
def addPackageInfo(self, name, platform, version, hostUrl):
|
||||
""" Called by the browser to list all of the "required"
|
||||
packages that were preloaded before starting the
|
||||
@ -809,7 +814,7 @@ def dummyAppRunner(tokens = [], argv = None):
|
||||
|
||||
if AppRunnerGlobal.appRunner:
|
||||
print "Already have AppRunner, not creating a new one."
|
||||
return
|
||||
return AppRunnerGlobal.appRunner
|
||||
|
||||
appRunner = AppRunner()
|
||||
appRunner.dummy = True
|
||||
|
@ -25,6 +25,7 @@ class HostInfo:
|
||||
assert appRunner or hostDir
|
||||
|
||||
self.hostUrl = hostUrl
|
||||
self.appRunner = appRunner
|
||||
self.hostDir = hostDir
|
||||
self.asMirror = asMirror
|
||||
|
||||
|
@ -532,16 +532,24 @@ class PackageInfo:
|
||||
if not urlbase:
|
||||
urlbase = self.descFileDirname + '/' + fileSpec.filename
|
||||
|
||||
# Build up a list of URL's to try downloading from.
|
||||
# Build up a list of URL's to try downloading from. Unlike
|
||||
# the C++ implementation in P3DPackage.cxx, here we build the
|
||||
# URL's in forward order.
|
||||
tryUrls = []
|
||||
|
||||
if self.host.appRunner and self.host.appRunner.superMirrorUrl:
|
||||
# We start with the "super mirror", if it's defined.
|
||||
url = self.host.appRunner.superMirrorUrl + urlbase
|
||||
tryUrls.append(url)
|
||||
|
||||
if self.host.mirrors:
|
||||
# Choose a mirror at random first, then a different
|
||||
# mirror.
|
||||
# Choose two mirrors at random.
|
||||
mirrors = self.host.mirrors[:]
|
||||
for i in range(2):
|
||||
mirror = random.choice(mirrors)
|
||||
mirrors.remove(mirror)
|
||||
tryUrls.append(mirror + urlbase)
|
||||
url = mirror + urlbase
|
||||
tryUrls.append(url)
|
||||
if not mirrors:
|
||||
break
|
||||
|
||||
|
@ -458,7 +458,7 @@ class Packager:
|
||||
continue
|
||||
|
||||
if mdef.exclude and mdef.implicit:
|
||||
# Don't bother mentioning implicity-excluded
|
||||
# Don't bother mentioning implicitly-excluded
|
||||
# (i.e. missing) modules.
|
||||
continue
|
||||
|
||||
@ -1529,10 +1529,8 @@ class Packager:
|
||||
# The following are config settings that the caller may adjust
|
||||
# before calling any of the command methods.
|
||||
|
||||
# These should each be a Filename, or None if they are not
|
||||
# filled in.
|
||||
# This should be set to a Filename.
|
||||
self.installDir = None
|
||||
self.persistDir = None
|
||||
|
||||
# The download URL at which these packages will eventually be
|
||||
# hosted.
|
||||
|
@ -14,6 +14,12 @@ from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename
|
||||
# and then a number of smaller, optional packages, which may or may
|
||||
# not be needed by any one particular application.
|
||||
|
||||
packager.setHost('file:///home/drose/p3dstage',
|
||||
mirrors = ['file:///home/drose/p3dstage_mirror1',
|
||||
'file:///home/drose/p3dstage_mirror2',
|
||||
'file:///home/drose/p3dstage_mirror3',
|
||||
'file:///home/drose/p3dstage_mirror4'])
|
||||
|
||||
class coreapi(solo):
|
||||
# The special "coreapi" package. As a "solo", this is just a
|
||||
# single .dll (or dylib, or whatever).
|
||||
@ -102,6 +108,7 @@ class panda3d(package):
|
||||
'direct.gui.*',
|
||||
'direct.interval.*',
|
||||
'direct.particles.*',
|
||||
'direct.p3d.*',
|
||||
'direct.showbase.*',
|
||||
'direct.showutil.*',
|
||||
'direct.stdpy.*')
|
||||
|
@ -61,15 +61,6 @@ Options:
|
||||
This option may be repeated as necessary. These directories may
|
||||
also be specified with the pdef-path Config.prc variable.
|
||||
|
||||
-d persist_dir
|
||||
The full path to a local directory that retains persistant state
|
||||
between publishes. This directory structure keeps files that are
|
||||
used to build patches for future releases. You should keep this
|
||||
directory structure around for as long as you plan to support
|
||||
this package. If this directory structure does not exist or is
|
||||
empty, patches will not be created for this publish; but the
|
||||
directory structure will be populated for the next publish.
|
||||
|
||||
-u host_url
|
||||
Specifies the URL to the download server that will eventually
|
||||
host these packages (that is, the public URL of the install
|
||||
@ -119,7 +110,7 @@ packager = Packager.Packager()
|
||||
buildPatches = False
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'i:ps:d:DP:u:n:h')
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'i:ps:DP:u:n:h')
|
||||
except getopt.error, msg:
|
||||
usage(1, msg)
|
||||
|
||||
@ -130,8 +121,6 @@ for opt, arg in opts:
|
||||
buildPatches = True
|
||||
elif opt == '-s':
|
||||
packager.installSearch.appendDirectory(Filename.fromOsSpecific(arg))
|
||||
elif opt == '-d':
|
||||
packager.persistDir = Filename.fromOsSpecific(arg)
|
||||
elif opt == '-D':
|
||||
packager.allowPythonDev = True
|
||||
elif opt == '-P':
|
||||
|
@ -36,6 +36,7 @@ static const string default_plugin_filename = "p3d_plugin";
|
||||
|
||||
P3D_initialize_func *P3D_initialize;
|
||||
P3D_finalize_func *P3D_finalize;
|
||||
P3D_set_super_mirror_func *P3D_set_super_mirror;
|
||||
P3D_new_instance_func *P3D_new_instance;
|
||||
P3D_instance_start_func *P3D_instance_start;
|
||||
P3D_instance_finish_func *P3D_instance_finish;
|
||||
@ -187,6 +188,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
// Now get all of the function pointers.
|
||||
P3D_initialize = (P3D_initialize_func *)get_func(module, "P3D_initialize");
|
||||
P3D_finalize = (P3D_finalize_func *)get_func(module, "P3D_finalize");
|
||||
P3D_set_super_mirror = (P3D_set_super_mirror_func *)get_func(module, "P3D_set_super_mirror");
|
||||
P3D_new_instance = (P3D_new_instance_func *)get_func(module, "P3D_new_instance");
|
||||
P3D_instance_start = (P3D_instance_start_func *)get_func(module, "P3D_instance_start");
|
||||
P3D_instance_finish = (P3D_instance_finish_func *)get_func(module, "P3D_instance_finish");
|
||||
@ -226,6 +228,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
// Ensure that all of the function pointers have been found.
|
||||
if (P3D_initialize == NULL ||
|
||||
P3D_finalize == NULL ||
|
||||
P3D_set_super_mirror == NULL ||
|
||||
P3D_new_instance == NULL ||
|
||||
P3D_instance_start == NULL ||
|
||||
P3D_instance_finish == NULL ||
|
||||
@ -265,6 +268,7 @@ load_plugin(const string &p3d_plugin_filename,
|
||||
<< "Some function pointers not found:"
|
||||
<< "\nP3D_initialize = " << P3D_initialize
|
||||
<< "\nP3D_finalize = " << P3D_finalize
|
||||
<< "\nP3D_set_super_mirror = " << P3D_set_super_mirror
|
||||
<< "\nP3D_new_instance = " << P3D_new_instance
|
||||
<< "\nP3D_instance_start = " << P3D_instance_start
|
||||
<< "\nP3D_instance_finish = " << P3D_instance_finish
|
||||
@ -358,6 +362,7 @@ unload_dso() {
|
||||
|
||||
P3D_initialize = NULL;
|
||||
P3D_finalize = NULL;
|
||||
P3D_set_super_mirror = NULL;
|
||||
P3D_new_instance = NULL;
|
||||
P3D_instance_start = NULL;
|
||||
P3D_instance_finish = NULL;
|
||||
|
@ -22,6 +22,7 @@ using namespace std;
|
||||
|
||||
extern P3D_initialize_func *P3D_initialize;
|
||||
extern P3D_finalize_func *P3D_finalize;
|
||||
extern P3D_set_super_mirror_func *P3D_set_super_mirror;
|
||||
extern P3D_new_instance_func *P3D_new_instance;
|
||||
extern P3D_instance_start_func *P3D_instance_start;
|
||||
extern P3D_instance_finish_func *P3D_instance_finish;
|
||||
|
@ -847,10 +847,6 @@ start_download(P3DDownload *download) {
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
// Since we're downloading something, we might as well check all
|
||||
// contents files from this point on.
|
||||
inst_mgr->reset_verify_contents();
|
||||
|
||||
int download_id = inst_mgr->get_unique_id();
|
||||
download->set_download_id(download_id);
|
||||
|
||||
@ -912,6 +908,9 @@ make_xml() {
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
xinstance->SetAttribute("root_dir", inst_mgr->get_root_dir());
|
||||
if (!inst_mgr->get_super_mirror().empty()) {
|
||||
xinstance->SetAttribute("super_mirror", inst_mgr->get_super_mirror());
|
||||
}
|
||||
|
||||
TiXmlElement *xfparams = _fparams.make_xml();
|
||||
xinstance->LinkEndChild(xfparams);
|
||||
|
@ -122,6 +122,16 @@ get_trusted_environment() const {
|
||||
return _trusted_environment;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_super_mirror
|
||||
// Access: Public
|
||||
// Description: Returns the "super mirror" URL. See p3d_plugin.h.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline const string &P3DInstanceManager::
|
||||
get_super_mirror() const {
|
||||
return _super_mirror_url;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_num_instances
|
||||
// Access: Public
|
||||
|
@ -296,6 +296,21 @@ initialize(const string &contents_filename, const string &download_url,
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::set_super_mirror
|
||||
// Access: Public
|
||||
// Description: Specifies the "super mirror" URL. See p3d_plugin.h.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
set_super_mirror(const string &super_mirror_url) {
|
||||
_super_mirror_url = super_mirror_url;
|
||||
|
||||
// Make sure it ends with a slash.
|
||||
if (!_super_mirror_url.empty() && _super_mirror_url[_super_mirror_url.size() - 1] != '/') {
|
||||
_super_mirror_url += '/';
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::create_instance
|
||||
// Access: Public
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
inline const string &get_log_pathname() const;
|
||||
inline bool get_trusted_environment() const;
|
||||
|
||||
void set_super_mirror(const string &super_mirror_url);
|
||||
inline const string &get_super_mirror() const;
|
||||
|
||||
P3DInstance *
|
||||
create_instance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
@ -129,6 +132,7 @@ private:
|
||||
string _log_pathname;
|
||||
string _temp_directory;
|
||||
bool _trusted_environment;
|
||||
string _super_mirror_url;
|
||||
|
||||
P3D_object *_undefined_object;
|
||||
P3D_object *_none_object;
|
||||
|
@ -945,6 +945,22 @@ start_download(P3DPackage::DownloadType dtype, const string &urlbase,
|
||||
}
|
||||
}
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
if (dtype == DT_contents_file && inst_mgr->get_verify_contents()) {
|
||||
// When we're dowloading the contents file with verify_contents
|
||||
// true, we always go straight to the authoritative host, not even
|
||||
// to the super-mirror.
|
||||
|
||||
} else {
|
||||
// In other cases, if the "super mirror" is enabled, we try that
|
||||
// first.
|
||||
if (!inst_mgr->get_super_mirror().empty()) {
|
||||
string url = inst_mgr->get_super_mirror() + urlbase;
|
||||
download->_try_urls.push_back(url);
|
||||
}
|
||||
}
|
||||
|
||||
// OK, start the download.
|
||||
assert(!download->_try_urls.empty());
|
||||
url = download->_try_urls.back();
|
||||
|
@ -1116,8 +1116,13 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) {
|
||||
root_dir = "";
|
||||
}
|
||||
|
||||
const char *super_mirror = xinstance->Attribute("super_mirror");
|
||||
if (super_mirror == NULL) {
|
||||
super_mirror = "";
|
||||
}
|
||||
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char *)"setInstanceInfo", (char *)"s", root_dir);
|
||||
(_runner, (char *)"setInstanceInfo", (char *)"ss", root_dir, super_mirror);
|
||||
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
|
@ -850,8 +850,9 @@ start_p3dpython(P3DInstance *inst) {
|
||||
_env += python_path;
|
||||
_env += '\0';
|
||||
|
||||
// Let's leave PYTHONHOME empty. Setting it adds junk to our
|
||||
// carefully-constructed PYTHONPATH.
|
||||
_env += "PYTHONHOME=";
|
||||
_env += _python_root_dir;
|
||||
_env += '\0';
|
||||
|
||||
_env += "PRC_PATH=";
|
||||
|
@ -84,11 +84,23 @@ P3D_finalize() {
|
||||
P3DInstanceManager::delete_global_ptr();
|
||||
}
|
||||
|
||||
void
|
||||
P3D_set_super_mirror(const char *super_mirror_url) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
if (super_mirror_url == NULL) {
|
||||
super_mirror_url = "";
|
||||
}
|
||||
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
inst_mgr->set_super_mirror(super_mirror_url);
|
||||
RELEASE_LOCK(_api_lock);
|
||||
}
|
||||
|
||||
P3D_instance *
|
||||
P3D_new_instance(P3D_request_ready_func *func,
|
||||
const P3D_token tokens[], size_t num_tokens,
|
||||
int argc, const char *argv[], void *user_data) {
|
||||
nout << "new_instance\n";
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
@ -101,7 +113,6 @@ P3D_new_instance(P3D_request_ready_func *func,
|
||||
bool
|
||||
P3D_instance_start(P3D_instance *instance, bool is_local,
|
||||
const char *p3d_filename) {
|
||||
nout << "instance_start\n";
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
if (p3d_filename == NULL) {
|
||||
p3d_filename = "";
|
||||
@ -138,7 +149,6 @@ P3D_instance_setup_window(P3D_instance *instance,
|
||||
int win_x, int win_y,
|
||||
int win_width, int win_height,
|
||||
P3D_window_handle parent_window) {
|
||||
nout << "setup_window\n";
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
P3DWindowParams wparams(window_type, win_x, win_y,
|
||||
win_width, win_height, parent_window);
|
||||
|
@ -145,6 +145,22 @@ P3D_initialize_func(int api_version, const char *contents_filename,
|
||||
typedef void
|
||||
P3D_finalize_func();
|
||||
|
||||
/* This function defines a "super mirror" URL: a special URL that is
|
||||
consulted first whenever downloading any package referenced by a
|
||||
p3d file. This setting is global, and affects all package
|
||||
downloads across all instances. The main purpose of this is to
|
||||
facilitate local distribution of the Panda3D runtime build, to
|
||||
allow applications to ship themselves totally self-contained. If
|
||||
you install the appropriate Panda3D package files into a directory
|
||||
on disk, and set the "super mirror" to a file:// URL that
|
||||
references that directory, then users will be able to run your p3d
|
||||
file without necessarily having an internet connection.
|
||||
|
||||
This normally should be set only by the panda3d standalone runtime
|
||||
executable, not by a web plugin. */
|
||||
typedef void
|
||||
P3D_set_super_mirror_func(const char *super_mirror_url);
|
||||
|
||||
/********************** INSTANCE MANAGEMENT **************************/
|
||||
|
||||
/* The following interfaces define the API to manage individual
|
||||
@ -852,6 +868,7 @@ P3D_instance_handle_event_func(P3D_instance *instance, P3D_event_data event);
|
||||
/* Define all of the actual prototypes for the above functions. */
|
||||
EXPCL_P3D_PLUGIN P3D_initialize_func P3D_initialize;
|
||||
EXPCL_P3D_PLUGIN P3D_finalize_func P3D_finalize;
|
||||
EXPCL_P3D_PLUGIN P3D_set_super_mirror_func P3D_set_super_mirror;
|
||||
|
||||
EXPCL_P3D_PLUGIN P3D_new_instance_func P3D_new_instance;
|
||||
EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
|
||||
|
@ -22,6 +22,7 @@
|
||||
// definition, even though we don't link with dtool.
|
||||
#include "dtool_platform.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sstream>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@ -66,10 +67,11 @@ run(int argc, char *argv[]) {
|
||||
// We prefix a "+" sign to tell gnu getopt not to parse options
|
||||
// following the first not-option parameter. (These will be passed
|
||||
// into the sub-process.)
|
||||
const char *optstr = "+mu:p:fw:t:s:o:l:ih";
|
||||
const char *optstr = "+mu:M:p:fw:t:s:o:l:ih";
|
||||
|
||||
bool allow_multiple = false;
|
||||
string download_url = PANDA_PACKAGE_HOST_URL;
|
||||
string super_mirror_url;
|
||||
string this_platform = DTOOL_PLATFORM;
|
||||
bool verify_contents = false;
|
||||
|
||||
@ -89,6 +91,10 @@ run(int argc, char *argv[]) {
|
||||
download_url = optarg;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
super_mirror_url = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
this_platform = optarg;
|
||||
break;
|
||||
@ -181,16 +187,36 @@ run(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure it ends with a slash.
|
||||
// Make sure the download URL ends with a slash.
|
||||
if (!download_url.empty() && download_url[download_url.length() - 1] != '/') {
|
||||
download_url += '/';
|
||||
}
|
||||
|
||||
// If the "super mirror" URL is a filename, convert it to a file:// url.
|
||||
if (!super_mirror_url.empty()) {
|
||||
if (!is_url(super_mirror_url)) {
|
||||
Filename filename = Filename::from_os_specific(super_mirror_url);
|
||||
filename.make_absolute();
|
||||
string path = filename.to_os_generic();
|
||||
if (!path.empty() && path[0] != '/') {
|
||||
// On Windows, a leading drive letter must be preceded by an
|
||||
// additional slash.
|
||||
path = "/" + path;
|
||||
}
|
||||
super_mirror_url = "file://" + path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!get_plugin(download_url, this_platform, verify_contents)) {
|
||||
cerr << "Unable to load Panda3D plugin.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set up the "super mirror" URL, if specified.
|
||||
if (!super_mirror_url.empty()) {
|
||||
P3D_set_super_mirror(super_mirror_url.c_str());
|
||||
}
|
||||
|
||||
int num_instance_filenames, num_instance_args;
|
||||
char **instance_filenames, **instance_args;
|
||||
|
||||
@ -682,16 +708,14 @@ P3D_instance *Panda3D::
|
||||
create_instance(const string &p3d, P3D_window_type window_type,
|
||||
int win_x, int win_y, int win_width, int win_height,
|
||||
P3D_window_handle parent_window, char **args, int num_args) {
|
||||
// If the supplied parameter name is a real file, pass it in on the
|
||||
// parameter list. Otherwise, assume it's a URL and let the plugin
|
||||
// download it.
|
||||
// Check to see if the p3d filename we were given is a URL, or a
|
||||
// local file.
|
||||
Filename p3d_filename = Filename::from_os_specific(p3d);
|
||||
string os_p3d_filename = p3d;
|
||||
bool is_local = false;
|
||||
if (p3d_filename.exists()) {
|
||||
bool is_local = !is_url(p3d);
|
||||
if (is_local) {
|
||||
p3d_filename.make_absolute();
|
||||
os_p3d_filename = p3d_filename.to_os_specific();
|
||||
is_local = true;
|
||||
}
|
||||
|
||||
// Build up the token list.
|
||||
@ -832,8 +856,17 @@ usage() {
|
||||
<< " code.\n\n"
|
||||
|
||||
<< " -u url\n"
|
||||
<< " Specify the URL of the Panda3D download server. The default is\n"
|
||||
<< " \"" << PANDA_PACKAGE_HOST_URL << "\" .\n\n"
|
||||
|
||||
<< " Specify the URL of the Panda3D download server. This is the host\n"
|
||||
<< " from which the plugin itself will be downloaded if necessary. The\n"
|
||||
<< " default is\n \"" << PANDA_PACKAGE_HOST_URL << "\" .\n\n"
|
||||
|
||||
<< " -M super_mirror_url\n"
|
||||
<< " Specifies the \"super mirror\" URL, the special URL that is consulted\n"
|
||||
<< " first before downloading any package file referenced by a p3d file.\n"
|
||||
<< " This is primarily intended to support pre-installing a downloadable\n"
|
||||
<< " Panda3D tree on the local machine, to allow p3d applications to\n"
|
||||
<< " execute without requiring an internet connection.\n\n"
|
||||
|
||||
<< " -p platform\n"
|
||||
<< " Specify the platform to masquerade as. The default is \""
|
||||
@ -888,6 +921,39 @@ parse_int_pair(char *arg, int &x, int &y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Panda3D::is_url
|
||||
// Access: Private, Static
|
||||
// Description: Returns true if the indicated string appears to be a
|
||||
// URL, with a leading http:// or file:// or whatever,
|
||||
// or false if it must be a local filename instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Panda3D::
|
||||
is_url(const string ¶m) {
|
||||
// We define a URL prefix as a sequence of at least two letters,
|
||||
// followed by a colon, followed by at least one slash.
|
||||
size_t p = 0;
|
||||
while (p < param.size() && isalpha(param[p])) {
|
||||
++p;
|
||||
}
|
||||
if (p < 2) {
|
||||
// Not enough letters.
|
||||
return false;
|
||||
}
|
||||
if (p >= param.size() || param[p] != ':') {
|
||||
// No colon.
|
||||
return false;
|
||||
}
|
||||
++p;
|
||||
if (p >= param.size() || param[p] != '/') {
|
||||
// No slash.
|
||||
return false;
|
||||
}
|
||||
|
||||
// It matches the rules.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Panda3D::report_downloading_package
|
||||
// Access: Private
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
void usage();
|
||||
bool parse_token(char *arg);
|
||||
bool parse_int_pair(char *arg, int &x, int &y);
|
||||
static bool is_url(const string ¶m);
|
||||
|
||||
void report_downloading_package(P3D_instance *instance);
|
||||
void report_download_complete(P3D_instance *instance);
|
||||
|
@ -786,6 +786,8 @@ class Freezer:
|
||||
continue
|
||||
if origName in self.previousModules:
|
||||
continue
|
||||
if origName in self.modules:
|
||||
continue
|
||||
|
||||
# This module is missing. Let it be missing in the
|
||||
# runtime also.
|
||||
|
Loading…
x
Reference in New Issue
Block a user