multiplatform support for plugin loader: run 32-bit or 64-bit version; whichever one is provided.

This commit is contained in:
David Rose 2012-09-27 23:00:23 +00:00
parent 0fa4376f8a
commit 0662ea7958
21 changed files with 458 additions and 104 deletions

View File

@ -124,6 +124,10 @@ class panda3d_import_manager:
if (cls.os.path.exists(lib + dll_ext)):
target = lib + dll_ext
break
if target:
# Once we find the first match, break all the way
# out--don't keep looking for a second match.
break
if target == None:
message = "DLL loader cannot find %s." % name
raise ImportError, message

View File

@ -28,13 +28,9 @@ class HostInfo:
there. At the moment, mirror folders do not download old
patch files from the server.
If you pass perPlatform = True, then files are unpacked into a
platform-specific directory, which is appropriate when you
might be downloading multiple platforms. The default is
perPlatform = False, which means all files are unpacked into
the host directory directly, without an intervening
platform-specific directory name. If asMirror is True, then
the default is perPlatform = True. """
perPlatform remains for historical reasons, but it is ignored.
Nowadays, all files are always unpacked into platform-specific
directories, even on the client. """
assert appRunner or rootDir or hostDir
@ -49,9 +45,7 @@ class HostInfo:
self.hostDir = hostDir
self.asMirror = asMirror
self.perPlatform = perPlatform
if perPlatform is None:
self.perPlatform = asMirror
self.perPlatform = True
# Initially false, this is set true when the contents file is
# successfully read.
@ -583,7 +577,7 @@ class HostInfo:
for pkey, package in pitems:
result.append(package)
else:
# If we maintain a a host for the current platform
# If we maintain a host for the current platform
# only (e.g. a client copy), then return only the
# current platform, or no particular platform.
package = platforms.get(PandaSystem.getPlatform(), None)

View File

@ -2197,6 +2197,14 @@ class Packager:
# The system PATH, for searching dll's and exe's.
self.executablePath = DSearchPath()
# By convention, we include sys.path at the front of
# self.executablePath, mainly to aid makepanda when building
# an rtdist build.
for dirname in sys.path:
self.executablePath.appendDirectory(Filename.fromOsSpecific(dirname))
# Now add the actual system search path.
if self.platform.startswith('win'):
self.addWindowsSearchPath(self.executablePath, "PATH")
elif self.platform.startswith('osx'):

View File

@ -241,7 +241,6 @@ for platform in platforms:
# Just print the error message and exit gracefully.
inst = sys.exc_info()[1]
print inst.args[0]
#raise
sys.exit(1)
# An explicit call to exit() is required to exit the program, when

View File

@ -62,7 +62,11 @@ P3DHost::
PackageMap &package_map = (*mi).second;
PackageMap::iterator pi;
for (pi = package_map.begin(); pi != package_map.end(); ++pi) {
delete (*pi).second;
PlatformPackages &ppackages = (*pi).second;
PlatformPackages::iterator ppi;
for (ppi = ppackages.begin(); ppi != ppackages.end(); ++ppi) {
delete (*ppi);
}
}
}
_packages.clear();
@ -356,14 +360,16 @@ read_xhost(TiXmlElement *xhost) {
////////////////////////////////////////////////////////////////////
P3DPackage *P3DHost::
get_package(const string &package_name, const string &package_version,
const string &package_seq, const string &alt_host) {
const string &package_platform, const string &package_seq,
const string &alt_host) {
if (!alt_host.empty()) {
if (_xcontents != NULL) {
// If we're asking for an alt host and we've already read our
// contents.xml file, then we already know all of our hosts, and
// we can start the package off with the correct host immediately.
P3DHost *new_host = get_alt_host(alt_host);
return new_host->get_package(package_name, package_version, package_seq);
return new_host->get_package(package_name, package_version,
package_platform, package_seq);
}
// If we haven't read contents.xml yet, we need to create the
@ -371,30 +377,44 @@ get_package(const string &package_name, const string &package_version,
// contents.xml, and it can migrate to its alt_host after that.
}
PackageMap &package_map = _packages[alt_host];
string key = package_name + "_" + package_version;
PlatformPackages &ppackages = _packages[alt_host][key];
PlatformPackages::iterator ppi;
P3DPackage *package = NULL;
string key = package_name + "_" + package_version;
PackageMap::iterator pi = package_map.find(key);
if (pi != package_map.end()) {
// We've previously installed this package.
package = (*pi).second;
// First, look for an exact match of the platform.
for (ppi = ppackages.begin(); ppi != ppackages.end(); ++ppi) {
if ((*ppi)->get_package_platform() == package_platform) {
package = *ppi;
break;
}
}
// If an exact match isn't found, look for a generic platform.
if (package == NULL) {
for (ppi = ppackages.begin(); ppi != ppackages.end(); ++ppi) {
if ((*ppi)->get_package_platform().empty()) {
package = *ppi;
break;
}
}
}
if (package != NULL) {
if (package->get_failed()) {
// If the package has previously failed, move it aside and try
// again (maybe it just failed because the user interrupted it).
nout << "Package " << key << " has previously failed; trying again.\n";
_failed_packages.push_back(package);
(*pi).second = NULL;
ppackages.erase(ppi);
package = NULL;
}
}
if (package == NULL) {
package =
new P3DPackage(this, package_name, package_version, alt_host);
package_map[key] = package;
new P3DPackage(this, package_name, package_version, package_platform, alt_host);
ppackages.push_back(package);
}
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
@ -403,10 +423,10 @@ get_package(const string &package_name, const string &package_version,
// believe we have a valid contents.xml file, then check the seq
// value in the contents.
FileSpec desc_file;
string platform, seq;
string seq;
bool solo;
if (get_package_desc_file(desc_file, platform, seq, solo,
package_name, package_version)) {
if (get_package_desc_file(desc_file, seq, solo,
package_name, package_version, package_platform)) {
nout << package_name << ": asked for seq " << package_seq
<< ", we have seq " << seq << "\n";
if (compare_seq(package_seq, seq) > 0) {
@ -421,6 +441,103 @@ get_package(const string &package_name, const string &package_version,
return package;
}
////////////////////////////////////////////////////////////////////
// Function: P3DHost::choose_suitable_platform
// Access: Public
// Description: Chooses the most appropriate platform for the
// indicated package (presumably the "panda3d" package),
// based on what this hardware supports and what is
// actually available.
////////////////////////////////////////////////////////////////////
bool P3DHost::
choose_suitable_platform(string &selected_platform,
const string &package_name,
const string &package_version,
const string &package_platform) {
if (_xcontents == NULL) {
return false;
}
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
TiXmlElement *xpackage;
// For the "panda3d" package only, we allow searching for any
// available supported platform.
if (package_name == "panda3d" && package_platform == "") {
int num_supported_platforms = inst_mgr->get_num_supported_platforms();
for (int pi = 0; pi < num_supported_platforms; ++pi) {
string supported_platform = inst_mgr->get_supported_platform(pi);
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 (version == NULL) {
version = "";
}
if (name != NULL && platform != NULL &&
package_name == name &&
supported_platform == platform &&
package_version == version) {
// Here's the matching package definition.
selected_platform = platform;
return true;
}
xpackage = xpackage->NextSiblingElement("package");
}
}
}
// Now, we look for an exact match for the current platform.
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 (version == NULL) {
version = "";
}
if (name != NULL && platform != NULL &&
package_name == name &&
package_platform == platform &&
package_version == version) {
// Here's the matching package definition.
selected_platform = platform;
return true;
}
xpackage = xpackage->NextSiblingElement("package");
}
// Look again, this time looking for a non-platform-specific version.
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 (platform == NULL) {
platform = "";
}
if (version == NULL) {
version = "";
}
if (name != NULL &&
package_name == name &&
*platform == '\0' &&
package_version == version) {
selected_platform = platform;
return true;
}
xpackage = xpackage->NextSiblingElement("package");
}
// Couldn't find a suitable platform.
return false;
}
////////////////////////////////////////////////////////////////////
// Function: P3DHost::get_package_desc_file
// Access: Public
@ -433,11 +550,11 @@ get_package(const string &package_name, const string &package_version,
////////////////////////////////////////////////////////////////////
bool P3DHost::
get_package_desc_file(FileSpec &desc_file, // out
string &package_platform, // out
string &package_seq, // out
bool &package_solo, // out
const string &package_name, // in
const string &package_version) { // in
const string &package_version, // in
const string &package_platform) { // in
if (_xcontents == NULL) {
return false;
}
@ -461,12 +578,11 @@ get_package_desc_file(FileSpec &desc_file, // out
}
if (name != NULL && platform != NULL &&
package_name == name &&
inst_mgr->get_platform() == platform &&
package_platform == platform &&
package_version == version) {
// Here's the matching package definition.
desc_file.load_xml(xpackage);
package_seq = seq;
package_platform = platform;
package_solo = false;
if (solo != NULL) {
package_solo = (atoi(solo) != 0);
@ -501,7 +617,6 @@ get_package_desc_file(FileSpec &desc_file, // out
// Here's the matching package definition.
desc_file.load_xml(xpackage);
package_seq = seq;
package_platform = platform;
package_solo = false;
if (solo != NULL) {
package_solo = (atoi(solo) != 0);
@ -529,16 +644,19 @@ forget_package(P3DPackage *package, const string &alt_host) {
string key = package->get_package_name() + "_" + package->get_package_version();
nout << "Forgetting package " << key << "\n";
PackageMap &package_map = _packages[alt_host];
PlatformPackages &ppackages = _packages[alt_host][key];
// Hmm, this is a memory leak. But we allow it to remain, since
// it's an unusual circumstance (uninstalling), and it's safer to
// leak than to risk a floating pointer.
package_map.erase(key);
PlatformPackages::iterator ppi = find(ppackages.begin(), ppackages.end(), package);
if (ppi != ppackages.end()) {
// Hmm, this is a memory leak. But we allow it to remain, since
// it's an unusual circumstance (uninstalling), and it's safer to
// leak than to risk a floating pointer.
ppackages.erase(ppi);
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DHost::migrate_package
// Function: P3DHost::migrate_package_host
// Access: Public
// Description: This is called by P3DPackage when it migrates from
// this host to its final alt_host, after downloading
@ -546,20 +664,21 @@ forget_package(P3DPackage *package, const string &alt_host) {
// true URL for its target alt_host.
////////////////////////////////////////////////////////////////////
void P3DHost::
migrate_package(P3DPackage *package, const string &alt_host, P3DHost *new_host) {
migrate_package_host(P3DPackage *package, const string &alt_host, P3DHost *new_host) {
assert(new_host != this);
assert(new_host == get_alt_host(alt_host));
string key = package->get_package_name() + "_" + package->get_package_version();
PackageMap &package_map = _packages[alt_host];
PackageMap::iterator pi = package_map.find(key);
assert(pi != package_map.end());
package_map.erase(pi);
PlatformPackages &ppackages = _packages[alt_host][key];
PackageMap &new_package_map = new_host->_packages[""];
bool inserted = new_package_map.insert(PackageMap::value_type(key, package)).second;
assert(inserted);
PlatformPackages::iterator ppi = find(ppackages.begin(), ppackages.end(), package);
assert(ppi != ppackages.end());
ppackages.erase(ppi);
PlatformPackages &new_ppackages = new_host->_packages[""][key];
new_ppackages.push_back(package);
}
////////////////////////////////////////////////////////////////////
@ -635,8 +754,12 @@ uninstall() {
PackageMap &package_map = (*mi).second;
PackageMap::iterator pi;
for (pi = package_map.begin(); pi != package_map.end(); ++pi) {
P3DPackage *package = (*pi).second;
package->uninstall();
PlatformPackages &ppackages = (*pi).second;
PlatformPackages::iterator ppi;
for (ppi = ppackages.begin(); ppi != ppackages.end(); ++ppi) {
P3DPackage *package = (*ppi);
package->uninstall();
}
}
}

View File

@ -54,17 +54,22 @@ public:
P3DPackage *get_package(const string &package_name,
const string &package_version,
const string &package_platform,
const string &package_seq,
const string &alt_host = "");
bool choose_suitable_platform(string &selected_platform,
const string &package_name,
const string &package_version,
const string &package_platform);
bool get_package_desc_file(FileSpec &desc_file,
string &package_platform,
string &package_seq,
bool &package_solo,
const string &package_name,
const string &package_version);
const string &package_version,
const string &package_platform);
void forget_package(P3DPackage *package, const string &alt_host = "");
void migrate_package(P3DPackage *package, const string &alt_host, P3DHost *new_host);
void migrate_package_host(P3DPackage *package, const string &alt_host, P3DHost *new_host);
void choose_random_mirrors(vector<string> &result, int num_mirrors);
void add_mirror(string mirror_url);
@ -97,7 +102,8 @@ private:
typedef map<string, string> AltHosts;
AltHosts _alt_hosts;
typedef map<string, P3DPackage *> PackageMap;
typedef vector<P3DPackage *> PlatformPackages;
typedef map<string, PlatformPackages> PackageMap;
typedef map<string, PackageMap> Packages;
Packages _packages;
typedef vector<P3DPackage *> FailedPackages;

View File

@ -60,6 +60,25 @@ get_session_key() const {
return _session_key;
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstance::get_session_platform
// Access: Public
// Description: Returns the platform of this particular session.
// Before the panda3d package has been seen, this is the
// empty string; once we have downloaded the info file
// for the panda3d package, it is filled in with
// whatever platform is provided (that we're also
// runtime-compatible with).
//
// Presumably all of the platform-specific packages that
// are downloaded subsequently must be of the exact same
// platform.
////////////////////////////////////////////////////////////////////
inline const string &P3DInstance::
get_session_platform() const {
return _session_platform;
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstance::get_session
// Access: Public

View File

@ -146,7 +146,7 @@ P3DInstance(P3D_request_ready_func *func,
_failed = false;
_session = NULL;
_auth_session = NULL;
_panda3d = NULL;
_panda3d_package = NULL;
_splash_window = NULL;
_instance_window_opened = false;
_instance_window_attached = false;
@ -241,7 +241,7 @@ P3DInstance(P3D_request_ready_func *func,
// put up a splash image (for instance, the above IT_download image)
// while we download the real contents.
P3DHost *host = inst_mgr->get_host(inst_mgr->get_host_url());
_image_package = host->get_package("images", "", "");
_image_package = host->get_package("images", "", "", "");
if (_image_package != NULL) {
_image_package->add_instance(this);
}
@ -774,7 +774,7 @@ get_request() {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DHost *host = inst_mgr->get_host(host_url);
if (package_name != NULL) {
P3DPackage *package = host->get_package(package_name, package_version, "");
P3DPackage *package = host->get_package(package_name, package_version, _session_platform, "");
host->forget_package(package);
} else {
// If a NULL package name is given, forget the whole host.
@ -1066,8 +1066,9 @@ add_package(const string &name, const string &version, const string &seq,
// get its additional host information.
get_host_info(host);
}
P3DPackage *package = host->get_package(name, version, seq, alt_host);
P3DPackage *package = host->get_package(name, version, _session_platform,
seq, alt_host);
add_package(package);
}
@ -1087,7 +1088,7 @@ add_package(P3DPackage *package) {
}
if (package->get_package_name() == "panda3d") {
_panda3d = package;
_panda3d_package = package;
}
_packages.push_back(package);
@ -1125,6 +1126,9 @@ remove_package(P3DPackage *package) {
if (package == _p3dcert_package) {
_p3dcert_package = NULL;
}
if (package == _panda3d_package) {
_panda3d_package = NULL;
}
set_failed();
}
@ -1890,7 +1894,7 @@ check_p3d_signature() {
// We have to go download this package.
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DHost *host = inst_mgr->get_host(inst_mgr->get_host_url());
_certlist_package = host->get_package("certlist", "", "");
_certlist_package = host->get_package("certlist", "", "", "");
if (_certlist_package != NULL) {
_certlist_package->add_instance(this);
}
@ -1931,7 +1935,7 @@ mark_p3d_untrusted() {
// We have to go download this package.
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DHost *host = inst_mgr->get_host(inst_mgr->get_host_url());
_p3dcert_package = host->get_package("p3dcert", "", "");
_p3dcert_package = host->get_package("p3dcert", "", "", "");
if (_p3dcert_package != NULL) {
_p3dcert_package->add_instance(this);
}
@ -2009,20 +2013,10 @@ mark_p3d_trusted() {
_main_object->set_bool_property("trusted", true);
send_notify("onauth");
// Now that we're all set up, start downloading the required
// Now that we're all set up, grab the panda3d package. We need to
// examine this before we can start to download the remaining
// packages.
add_packages();
// Until we've done all of the above processing, we haven't fully
// committed to setting the trusted flag. (Setting this flag down
// here instead of a few lines above avoids starting the instance in
// add_packages(), before we've had a chance to finish processing
// this method.)
_p3d_trusted = true;
if (get_packages_ready()) {
mark_download_complete();
}
add_panda3d_package();
}
////////////////////////////////////////////////////////////////////
@ -2132,6 +2126,48 @@ scan_app_desc_file(TiXmlDocument *doc) {
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstance::add_panda3d_package
// Access: Private
// Description: Adds the "panda3d" package only. This package must
// be downloaded first, and its desc file examined,
// before we can begin downloading the other packages.
////////////////////////////////////////////////////////////////////
void P3DInstance::
add_panda3d_package() {
assert(!_packages_specified);
assert(_panda3d_package == NULL);
if (_xpackage == NULL) {
return;
}
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
TiXmlElement *xrequires = _xpackage->FirstChildElement("requires");
while (xrequires != NULL) {
const char *name = xrequires->Attribute("name");
const char *host_url = xrequires->Attribute("host");
if (name != NULL && host_url != NULL && strcmp(name, "panda3d") == 0) {
const char *version = xrequires->Attribute("version");
if (version == NULL) {
version = "";
}
const char *seq = xrequires->Attribute("seq");
if (seq == NULL) {
seq = "";
}
P3DHost *host = inst_mgr->get_host(host_url);
add_package(name, version, seq, host);
return;
}
xrequires = xrequires->NextSiblingElement("requires");
}
nout << "No panda3d package found in " << _fparams.get_p3d_filename() << "\n";
set_failed();
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstance::add_packages
// Access: Private
@ -2171,6 +2207,16 @@ add_packages() {
_packages_specified = true;
consider_start_download();
// Now that we've scanned the p3d file, and prepared the list of
// packages, it's safe to set the trusted flag.
_p3d_trusted = true;
// If the packages are already downloaded, start the instance
// rolling.
if (get_packages_ready()) {
mark_download_complete();
}
}
@ -2689,8 +2735,10 @@ make_splash_window() {
// Don't know where to put it yet.
return;
}
if (_wparams.get_window_type() == P3D_WT_hidden) {
// We're hidden, and so is the splash window.
if (_wparams.get_window_type() == P3D_WT_hidden && !is_failed()) {
// We're hidden, and so is the splash window. (But if we've got a
// failure case to report, we don't care and create the splash
// window anyway.)
return;
}
@ -2901,6 +2949,26 @@ report_package_info_ready(P3DPackage *package) {
return;
}
if (package == _panda3d_package && !_packages_specified) {
// Another special case. Once the special panda3d package is
// ready to download (and we know what platform it belongs to), we
// can begin to download the remaining required packages.
string package_platform = package->get_package_platform();
if (!package_platform.empty() && _session_platform.empty()) {
// From now on, all platform-specific files downloaded by this
// session will be for this platform.
_session_platform = package_platform;
}
if (_session_platform != package_platform) {
nout << "Error: session is " << _session_platform
<< ", but we somehow got panda3d for " << package_platform << "\n";
set_failed();
return;
}
add_packages();
}
// Now that the package's info is ready, we know its set of required
// packages, and we can add these to the list.
P3DPackage::Requires::const_iterator ri;

View File

@ -88,6 +88,7 @@ public:
inline int get_instance_id() const;
inline const string &get_session_key() const;
const string &get_log_pathname() const;
inline const string &get_session_platform() const;
inline P3DSession *get_session() const;
@ -176,6 +177,7 @@ private:
void mark_p3d_untrusted();
void mark_p3d_trusted();
void scan_app_desc_file(TiXmlDocument *doc);
void add_panda3d_package();
void add_packages();
string find_alt_host_url(const string &host_url, const string &alt_host);
void get_host_info(P3DHost *host);
@ -286,6 +288,7 @@ private:
int _instance_id;
string _session_key;
string _log_basename;
string _session_platform;
string _prc_name;
string _start_dir;
bool _hidden;
@ -356,7 +359,7 @@ private:
// We keep the _panda3d pointer separately because it's so
// important, but it's in the above vector also.
P3DPackage *_panda3d;
P3DPackage *_panda3d_package;
typedef map<int, P3DDownload *> Downloads;
Downloads _downloads;

View File

@ -200,6 +200,38 @@ get_console_environment() const {
return _console_environment;
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstanceManager::get_num_supported_platforms
// Access: Public
// Description: Returns the number of different supported platforms
// available in get_supported_platform().
////////////////////////////////////////////////////////////////////
inline int P3DInstanceManager::
get_num_supported_platforms() const {
return (int)_supported_platforms.size();
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstanceManager::get_supported_platform
// Access: Public
// Description: Returns the nth supported platform, where 0 <= n <
// get_num_supported_platforms().
//
// A given runtime environment may support multiple
// different platforms, e.g. win32 or win64, with the
// restriction that all platform-specific packages
// (beginning from panda3d), must be the same platform.
//
// This function enumerates the different platforms that
// the current runtime environment will support, in
// order of preference--preferred platforms appear first
// in the list.
////////////////////////////////////////////////////////////////////
inline const string &P3DInstanceManager::
get_supported_platform(int n) const {
return _supported_platforms.at(n);
}
////////////////////////////////////////////////////////////////////
// Function: P3DInstanceManager::get_plugin_major_version
// Access: Public

View File

@ -38,6 +38,7 @@
#include <shlobj.h>
#include <io.h> // chmod()
#include <direct.h> // rmdir()
#include <windows.h> // GetModuleHandle() etc.
#else
#include <sys/stat.h>
#include <signal.h>
@ -211,9 +212,32 @@ initialize(int api_version, const string &contents_filename,
}
if (_platform.empty()) {
// If the platform is compiled in (as opposed to passed in by the
// caller), we might in fact support multiple platforms.
_platform = DTOOL_PLATFORM;
if (_platform == "win64") {
_supported_platforms.push_back("win64");
_supported_platforms.push_back("win32");
} else if (_platform == "win32") {
// This is a WIN32 process, but determine if the underlying OS
// actually supports WIN64.
if (supports_win64()) {
_supported_platforms.push_back("win64");
}
_supported_platforms.push_back("win32");
}
// TODO: OSX, Linux multiplatform support. Just add the
// appropriate platform strings to _supported_platforms.
}
if (_supported_platforms.empty()) {
// We always support at least the specific platform on which we're
// running.
_supported_platforms.push_back(_platform);
}
#ifdef P3D_PLUGIN_LOG_DIRECTORY
if (_log_directory.empty()) {
_log_directory = P3D_PLUGIN_LOG_DIRECTORY;
@ -1520,3 +1544,20 @@ nt_thread_run() {
_notify_ready.release();
}
#ifdef _WIN32
bool P3DInstanceManager::
supports_win64() {
BOOL is_win64 = false;
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS _IsWow64Process;
_IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
if (_IsWow64Process != NULL) {
if (!_IsWow64Process(GetCurrentProcess(), &is_win64)) {
is_win64 = false;
}
}
return (is_win64 != 0);
}
#endif // _WIN32

View File

@ -76,6 +76,9 @@ public:
inline bool get_trusted_environment() const;
inline bool get_console_environment() const;
inline int get_num_supported_platforms() const;
inline const string &get_supported_platform(int n) const;
void set_plugin_version(int major, int minor, int sequence,
bool official, const string &distributor,
const string &coreapi_host_url,
@ -159,6 +162,10 @@ private:
THREAD_CALLBACK_DECLARATION(P3DInstanceManager, nt_thread_run);
void nt_thread_run();
#ifdef _WIN32
static bool supports_win64();
#endif // _WIN32
private:
bool _is_initialized;
bool _created_runtime_environment;
@ -185,6 +192,9 @@ private:
string _coreapi_set_ver;
string _super_mirror_url;
typedef vector<string> SupportedPlatforms;
SupportedPlatforms _supported_platforms;
P3D_object *_undefined_object;
P3D_object *_none_object;
P3D_object *_true_object;

View File

@ -108,6 +108,16 @@ get_package_version() const {
return _package_version;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPackage::get_package_platform
// Access: Public
// Description: Returns the platform string of this package.
////////////////////////////////////////////////////////////////////
inline const string &P3DPackage::
get_package_platform() const {
return _package_platform;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPackage::get_package_display_name
// Access: Public

View File

@ -44,10 +44,12 @@ const double P3DPackage::_patch_factor = 0.01;
////////////////////////////////////////////////////////////////////
P3DPackage::
P3DPackage(P3DHost *host, const string &package_name,
const string &package_version, const string &alt_host) :
const string &package_version, const string &package_platform,
const string &alt_host) :
_host(host),
_package_name(package_name),
_package_version(package_version),
_package_platform(package_platform),
_alt_host(alt_host)
{
_package_fullname = _package_name;
@ -611,7 +613,7 @@ host_got_contents_file() {
nout << "Migrating " << get_package_name() << " to alt_host "
<< _alt_host << ": " << new_host->get_host_url() << "\n";
if (new_host != _host) {
_host->migrate_package(this, _alt_host, new_host);
_host->migrate_package_host(this, _alt_host, new_host);
_host = new_host;
}
@ -632,11 +634,30 @@ host_got_contents_file() {
// instance, reloading it).
_host_contents_iseq = _host->get_contents_iseq();
// Now that we have a valid host, we can define the _package_dir.
// Now adjust the platform based on the available platforms
// provided.
assert(_alt_host.empty());
string new_platform;
if (_host->choose_suitable_platform(new_platform, _package_name, _package_version, _package_platform)) {
if (new_platform != _package_platform) {
nout << "Migrating " << get_package_name() << " from platform \""
<< _package_platform << "\" to platform \""
<< new_platform << "\"\n";
_package_platform = new_platform;
}
} else {
nout << "Couldn't find a platform for " << get_package_name() << ".\n";
}
// Now that we have a valid host and platform, we can define the
// _package_dir.
_package_dir = _host->get_host_dir() + string("/") + _package_name;
if (!_package_version.empty()) {
_package_dir += string("/") + _package_version;
}
if (!_package_platform.empty()) {
_package_dir += string("/") + _package_platform;
}
// Ensure the package directory exists; create it if it does not.
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
@ -661,11 +682,11 @@ download_desc_file() {
// exists, and is consistent with the server contents file, we don't
// need to re-download it.
string package_seq;
if (!_host->get_package_desc_file(_desc_file, _package_platform,
package_seq, _package_solo,
_package_name, _package_version)) {
if (!_host->get_package_desc_file(_desc_file, package_seq, _package_solo,
_package_name, _package_version,
_package_platform)) {
nout << "Couldn't find package " << _package_fullname
<< " in contents file.\n";
<< "/" << _package_platform << " in contents file.\n";
redownload_contents_file(NULL);
return;
}

View File

@ -44,6 +44,7 @@ private:
P3DPackage(P3DHost *host,
const string &package_name,
const string &package_version,
const string &package_platform,
const string &alt_host);
~P3DPackage();
@ -58,6 +59,7 @@ public:
inline const string &get_package_dir() const;
inline const string &get_package_name() const;
inline const string &get_package_version() const;
inline const string &get_package_platform() const;
inline const string &get_package_display_name() const;
string get_formatted_name() const;
inline const TiXmlElement *get_xconfig() const;

View File

@ -697,7 +697,7 @@ start_p3dpython(P3DInstance *inst) {
return;
}
if (inst->_panda3d == NULL) {
if (inst->_panda3d_package == NULL) {
nout << "Couldn't start Python: no panda3d dependency.\n";
set_failed();
return;
@ -705,7 +705,7 @@ start_p3dpython(P3DInstance *inst) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
_python_root_dir = inst->_panda3d->get_package_dir();
_python_root_dir = inst->_panda3d_package->get_package_dir();
replace_slashes(_python_root_dir);
// If we're not to be preserving the user's current directory, then
@ -823,10 +823,10 @@ start_p3dpython(P3DInstance *inst) {
// Allow package to override the name of the p3dpython executables.
const char *p3dpython_name_xconfig = NULL;
const char *p3dpythonw_name_xconfig = NULL;
const TiXmlElement *panda3d_xconfig = inst->_panda3d->get_xconfig();
const TiXmlElement *panda3d_xconfig = inst->_panda3d_package->get_xconfig();
if (panda3d_xconfig != NULL) {
p3dpython_name_xconfig = panda3d_xconfig->Attribute("p3dpython_name");
p3dpythonw_name_xconfig = panda3d_xconfig->Attribute("p3dpythonw_name");
p3dpython_name_xconfig = panda3d_xconfig->Attribute("p3dpython_name");
p3dpythonw_name_xconfig = panda3d_xconfig->Attribute("p3dpythonw_name");
}
string p3dpython_name = "p3dpython";
@ -1206,7 +1206,7 @@ start_p3dpython(P3DInstance *inst) {
// Get the filename of the Panda3D multifile. We need to pass this
// to p3dpython.
_mf_filename = inst->_panda3d->get_archive_file_pathname();
_mf_filename = inst->_panda3d_package->get_archive_file_pathname();
nout << "Attempting to start python from " << _p3dpython_exe << "\n";

View File

@ -83,6 +83,7 @@ run_command_line(int argc, char *argv[]) {
case 'p':
_this_platform = optarg;
_coreapi_platform = optarg;
break;
case 'n':
@ -506,7 +507,7 @@ read_contents_file(const Filename &contents_filename, bool fresh_download) {
const char *name = xpackage->Attribute("name");
if (name != NULL && strcmp(name, "coreapi") == 0) {
const char *platform = xpackage->Attribute("platform");
if (platform != NULL && _this_platform == string(platform)) {
if (platform != NULL && _coreapi_platform == string(platform)) {
_coreapi_dll.load_xml(xpackage);
const char *set_ver = xpackage->Attribute("set_ver");
if (set_ver != NULL) {
@ -524,7 +525,7 @@ read_contents_file(const Filename &contents_filename, bool fresh_download) {
if (!found_core_package) {
// Couldn't find the coreapi package description.
nout << "No coreapi package defined in contents file for "
<< _this_platform << "\n";
<< _coreapi_platform << "\n";
return false;
}

View File

@ -68,7 +68,11 @@ Panda3DBase(bool console_environment) {
_exit_with_last_instance = true;
_host_url = PANDA_PACKAGE_HOST_URL;
_this_platform = DTOOL_PLATFORM;
// Better to leave _this_platform set to the empty string until the
// user specifies otherwise; this allows the plugin to select a
// suitable platform at runtime.
_this_platform = "";
_coreapi_platform = DTOOL_PLATFORM;
_verify_contents = P3D_VC_none;
_contents_expiration = 0;
@ -235,12 +239,17 @@ handle_request(P3D_request *request) {
case P3D_RT_notify:
{
//cerr << "Notify: " << request->_request._notify._message << "\n";
if (strcmp(request->_request._notify._message, "ondownloadnext") == 0) {
// Tell the user we're downloading a package.
report_downloading_package(request->_instance);
} else if (strcmp(request->_request._notify._message, "ondownloadcomplete") == 0) {
// Tell the user we're done downloading.
report_download_complete(request->_instance);
} else if (strcmp(request->_request._notify._message, "onfail") == 0) {
// Failure! What else can we do?
cerr << "Failed to execute.\n";
exit(1);
}
}
break;

View File

@ -77,6 +77,7 @@ protected:
string _log_dirname;
string _log_basename;
string _this_platform;
string _coreapi_platform;
P3D_verify_contents _verify_contents;
time_t _contents_expiration;

View File

@ -786,13 +786,15 @@ class Freezer:
topName = parentName[:-2]
newTopName = newParentName[:-2]
parentNames = []
for dirname in self.getModulePath(topName):
for basename in os.listdir(dirname):
if os.path.exists(os.path.join(dirname, basename, '__init__.py')):
parentName = '%s.%s' % (topName, basename)
newParentName = '%s.%s' % (newTopName, basename)
if self.getModulePath(parentName):
parentNames.append((parentName, newParentName))
modulePath = self.getModulePath(topName)
if modulePath:
for dirname in modulePath:
for basename in os.listdir(dirname):
if os.path.exists(os.path.join(dirname, basename, '__init__.py')):
parentName = '%s.%s' % (topName, basename)
newParentName = '%s.%s' % (newTopName, basename)
if self.getModulePath(parentName):
parentNames.append((parentName, newParentName))
for parentName, newParentName in parentNames:
modules = self.getModuleStar(parentName)

View File

@ -4258,7 +4258,9 @@ if (RTDIST or RUNTIME):
TargetAdd('p3dcert.exe', input='plugin_wstring_encode.obj')
TargetAdd('p3dcert.exe', input='plugin_p3dCert.obj')
OPTS=['OPENSSL', 'FLTK', 'WINCOMCTL', 'WINSOCK']
else:
if (sys.platform=="darwin"): OPTS += ['OPT:2']
TargetAdd('p3dcert.exe', opts=OPTS)
elif (PkgSkip("WX")==0):
OPTS.append("WX")
TargetAdd('plugin_p3dCert.obj', opts=OPTS, input='p3dCert_wx.cxx')
TargetAdd('p3dcert.exe', input='plugin_mkdir_complete.obj')
@ -4266,9 +4268,8 @@ if (RTDIST or RUNTIME):
TargetAdd('p3dcert.exe', input='plugin_p3dCert.obj')
OPTS=['NOSTRIP', 'OPENSSL', 'WX', 'CARBON', 'WINOLE', 'WINOLEAUT', 'WINUSER', 'ADVAPI', 'WINSHELL', 'WINCOMCTL', 'WINGDI', 'WINCOMDLG']
if (sys.platform=="darwin"): OPTS.append("GL")
if (sys.platform=="darwin"): OPTS += ['OPT:2']
TargetAdd('p3dcert.exe', opts=OPTS)
if (sys.platform=="darwin"): OPTS += ['OPT:2']
TargetAdd('p3dcert.exe', opts=OPTS)
#
# DIRECTORY: direct/src/plugin_npapi/