From a737ebcc9069c9ffcc6c1831911a9e57be38d8ac Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 28 Sep 2012 20:26:22 +0000 Subject: [PATCH] per_platform flag, giving better compatibility with old p3d files --- direct/src/p3d/AppRunner.py | 8 ++- direct/src/p3d/HostInfo.py | 32 ++++++++---- direct/src/p3d/PackageInfo.py | 31 ++++++++--- direct/src/p3d/PackageMerger.py | 4 ++ direct/src/p3d/Packager.py | 21 ++++++-- direct/src/plugin/Sources.pp | 4 +- direct/src/plugin/p3dFileParams.cxx | 36 ++++++++----- direct/src/plugin/p3dFileParams.h | 1 + direct/src/plugin/p3dHost.cxx | 57 ++++++--------------- direct/src/plugin/p3dHost.h | 1 + direct/src/plugin/p3dInstance.cxx | 5 ++ direct/src/plugin/p3dInstanceManager.cxx | 6 +++ direct/src/plugin/p3dMainObject.cxx | 6 +-- direct/src/plugin/p3dPackage.cxx | 47 +++++++++++++---- direct/src/plugin/p3dPackage.h | 2 + direct/src/plugin/p3dPythonRun.cxx | 7 ++- direct/src/plugin/p3d_plugin_composite1.cxx | 1 + direct/src/plugin/xml_helpers.cxx | 43 ++++++++++++++++ direct/src/plugin/xml_helpers.h | 24 +++++++++ 19 files changed, 247 insertions(+), 89 deletions(-) create mode 100755 direct/src/plugin/xml_helpers.cxx create mode 100755 direct/src/plugin/xml_helpers.h diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index 8bdb8edc51..17b6a99b2f 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -104,6 +104,7 @@ class AppRunner(DirectObject): self.interactiveConsole = False self.initialAppImport = False self.trueFileIO = False + self.respectPerPlatform = None self.verifyContents = self.P3DVCNone @@ -493,7 +494,7 @@ class AppRunner(DirectObject): hostData = InstalledHostData(host, dirnode) if host: - for package in host.getAllPackages(): + for package in host.getAllPackages(includeAllPlatforms = True): packageDir = package.getPackageDir() if not packageDir.exists(): continue @@ -781,7 +782,7 @@ class AppRunner(DirectObject): self.deferredEvals = [] def setInstanceInfo(self, rootDir, logDirectory, superMirrorUrl, - verifyContents, main): + verifyContents, main, respectPerPlatform): """ Called by the browser to set some global information about the instance. """ @@ -807,6 +808,9 @@ class AppRunner(DirectObject): if main is not None: self.main = main + self.respectPerPlatform = respectPerPlatform + #self.notify.info("respectPerPlatform = %s" % (self.respectPerPlatform)) + # Now that we have rootDir, we can read the config file. self.readConfigXml() diff --git a/direct/src/p3d/HostInfo.py b/direct/src/p3d/HostInfo.py index 39d932d294..d72da61585 100644 --- a/direct/src/p3d/HostInfo.py +++ b/direct/src/p3d/HostInfo.py @@ -28,9 +28,16 @@ class HostInfo: there. At the moment, mirror folders do not download old patch files from the server. - perPlatform remains for historical reasons, but it is ignored. - Nowadays, all files are always unpacked into platform-specific - directories, even on the client. """ + 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. + + Note that perPlatform is also restricted by the individual + package's specification. """ assert appRunner or rootDir or hostDir @@ -45,7 +52,9 @@ class HostInfo: self.hostDir = hostDir self.asMirror = asMirror - self.perPlatform = True + self.perPlatform = perPlatform + if perPlatform is None: + self.perPlatform = asMirror # Initially false, this is set true when the contents file is # successfully read. @@ -372,8 +381,12 @@ class HostInfo: solo = int(xpackage.Attribute('solo') or '') except ValueError: solo = False + try: + perPlatform = int(xpackage.Attribute('per_platform') or '') + except ValueError: + perPlatform = False - package = self.__makePackage(name, platform, version, solo) + package = self.__makePackage(name, platform, version, solo, perPlatform) package.descFile = FileSpec() package.descFile.loadXml(xpackage) package.setupFilenames() @@ -493,7 +506,7 @@ class HostInfo: self.altHosts[keyword] = url xalthost = xalthost.NextSiblingElement('alt_host') - def __makePackage(self, name, platform, version, solo): + def __makePackage(self, name, platform, version, solo, perPlatform): """ Creates a new PackageInfo entry for the given name, version, and platform. If there is already a matching PackageInfo, returns it. """ @@ -507,7 +520,8 @@ class HostInfo: package = platforms.get(platform, None) if not package: package = PackageInfo(self, name, version, platform = platform, - solo = solo, asMirror = self.asMirror) + solo = solo, asMirror = self.asMirror, + perPlatform = perPlatform) platforms[platform] = package return package @@ -560,7 +574,7 @@ class HostInfo: return packages - def getAllPackages(self): + def getAllPackages(self, includeAllPlatforms = False): """ Returns a list of all available packages provided by this host. """ @@ -569,7 +583,7 @@ class HostInfo: items = self.packages.items() items.sort() for key, platforms in items: - if self.perPlatform: + if self.perPlatform or includeAllPlatforms: # If we maintain a different answer per platform, # return all of them. pitems = platforms.items() diff --git a/direct/src/p3d/PackageInfo.py b/direct/src/p3d/PackageInfo.py index bf13de1f50..6a173b57aa 100644 --- a/direct/src/p3d/PackageInfo.py +++ b/direct/src/p3d/PackageInfo.py @@ -78,13 +78,14 @@ class PackageInfo: return min(float(self.bytesDone) / float(self.bytesNeeded), 1) def __init__(self, host, packageName, packageVersion, platform = None, - solo = False, asMirror = False): + solo = False, asMirror = False, perPlatform = False): self.host = host self.packageName = packageName self.packageVersion = packageVersion self.platform = platform self.solo = solo self.asMirror = asMirror + self.perPlatform = perPlatform # This will be active while we are in the middle of a download # cycle. @@ -144,12 +145,23 @@ class PackageInfo: self.packageDir = Filename(self.packageDir, self.packageVersion) if self.host.perPlatform: - # The server directory contains the platform name, - # though the client directory normally doesn't (unless - # perPlatform is set true). + # If we're running on a special host that wants us to + # include the platform, we include it. + includePlatform = True + elif self.perPlatform and self.host.appRunner.respectPerPlatform: + # Otherwise, if our package spec wants us to include + # the platform (and our plugin knows about this), then + # we also include it. + includePlatform = True + else: + # Otherwise, we must be running legacy code + # somewhere--either an old package or an old + # plugin--and we therefore shouldn't include the + # platform in the directory hierarchy. + includePlatform = False - if self.platform: - self.packageDir = Filename(self.packageDir, self.platform) + if includePlatform and self.platform: + self.packageDir = Filename(self.packageDir, self.platform) return self.packageDir @@ -346,6 +358,13 @@ class PackageInfo: except ValueError: self.patchVersion = None + try: + perPlatform = int(xpackage.Attribute('per_platform') or '') + except ValueError: + perPlatform = False + if perPlatform != self.perPlatform: + self.notify.warning("per_platform disagreement on package %s" % (self.packageName)) + self.displayName = None xconfig = xpackage.FirstChildElement('config') if xconfig: diff --git a/direct/src/p3d/PackageMerger.py b/direct/src/p3d/PackageMerger.py index 505ae99dbb..12eff00233 100644 --- a/direct/src/p3d/PackageMerger.py +++ b/direct/src/p3d/PackageMerger.py @@ -41,6 +41,8 @@ class PackageMerger: self.version = xpackage.Attribute('version') solo = xpackage.Attribute('solo') self.solo = int(solo or '0') + perPlatform = xpackage.Attribute('per_platform') + self.perPlatform = int(perPlatform or '0') self.descFile = FileSpec() self.descFile.loadXml(xpackage) @@ -71,6 +73,8 @@ class PackageMerger: xpackage.SetAttribute('version', self.version) if self.solo: xpackage.SetAttribute('solo', '1') + if self.perPlatform: + xpackage.SetAttribute('per_platform', '1') self.descFile.storeXml(xpackage) self.packageSeq.storeXml(xpackage, 'seq') diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index 2d09243e75..6acd43cf03 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -187,12 +187,13 @@ class Packager: objects uniquely per package. """ return (self.packageName, self.platform, self.version) - def fromFile(self, packageName, platform, version, solo, + def fromFile(self, packageName, platform, version, solo, perPlatform, installDir, descFilename, importDescFilename): self.packageName = packageName self.platform = platform self.version = version self.solo = solo + self.perPlatform = perPlatform self.descFile = FileSpec() self.descFile.fromFile(installDir, descFilename) @@ -208,6 +209,8 @@ class Packager: self.version = xpackage.Attribute('version') solo = xpackage.Attribute('solo') self.solo = int(solo or '0') + perPlatform = xpackage.Attribute('per_platform') + self.perPlatform = int(perPlatform or '0') self.packageSeq = SeqValue() self.packageSeq.loadXml(xpackage, 'seq') @@ -235,6 +238,8 @@ class Packager: xpackage.SetAttribute('version', self.version) if self.solo: xpackage.SetAttribute('solo', '1') + if self.perPlatform: + xpackage.SetAttribute('per_platform', '1') self.packageSeq.storeXml(xpackage, 'seq') self.packageSetVer.storeXml(xpackage, 'set_ver') @@ -322,6 +327,9 @@ class Packager: # platform-specific. self.platform = None + # This is always true on modern packages. + self.perPlatform = True + # The arch string, though, is pre-loaded from the system # arch string, so we can sensibly call otool. self.arch = self.packager.arch @@ -722,6 +730,7 @@ class Packager: else: self.readDescFile() self.packageSeq += 1 + self.perPlatform = True # always true on modern packages. self.compressMultifile() self.writeDescFile() self.writeImportDescFile() @@ -734,7 +743,7 @@ class Packager: # Replace or add the entry in the contents. pe = Packager.PackageEntry() pe.fromFile(self.packageName, self.platform, self.version, - False, self.packager.installDir, + False, self.perPlatform, self.packager.installDir, self.packageDesc, self.packageImportDesc) pe.packageSeq = self.packageSeq pe.packageSetVer = self.packageSetVer @@ -753,6 +762,7 @@ class Packager: kinds of similar "solo" packages as well. """ self.considerPlatform() + self.perPlatform = False # Not true on "solo" packages. packageDir = self.packageName if self.platform: @@ -798,7 +808,7 @@ class Packager: # Replace or add the entry in the contents. pe = Packager.PackageEntry() pe.fromFile(self.packageName, self.platform, self.version, - True, self.packager.installDir, + True, self.perPlatform, self.packager.installDir, Filename(packageDir, file.newName), None) peOrig = self.packager.contents.get(pe.getKey(), None) if peOrig: @@ -1509,6 +1519,9 @@ class Packager: if not xpackage: return + perPlatform = xpackage.Attribute('per_platform') + self.perPlatform = int(perPlatform or '0') + self.packageSeq.loadXml(xpackage, 'seq') self.packageSetVer.loadXml(xpackage, 'set_ver') @@ -1554,6 +1567,8 @@ class Packager: xpackage.SetAttribute('platform', self.platform) if self.version: xpackage.SetAttribute('version', self.version) + if self.perPlatform: + xpackage.SetAttribute('per_platform', '1') if self.patchVersion: xpackage.SetAttribute('last_patch_version', self.patchVersion) diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 2078a3edbf..6f75f0bb03 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -70,6 +70,7 @@ p3dX11SplashWindow.h p3dX11SplashWindow.I \ p3dWindowParams.h p3dWindowParams.I \ plugin_get_x11.h \ + xml_helpers.h \ run_p3dpython.h #define COREAPI_INCLUDED_SOURCES \ @@ -104,7 +105,8 @@ p3dUndefinedObject.cxx \ p3dWinSplashWindow.cxx \ p3dX11SplashWindow.cxx \ - p3dWindowParams.cxx + p3dWindowParams.cxx \ + xml_helpers.cxx #begin lib_target diff --git a/direct/src/plugin/p3dFileParams.cxx b/direct/src/plugin/p3dFileParams.cxx index 3507463dc6..a5e2bddb50 100644 --- a/direct/src/plugin/p3dFileParams.cxx +++ b/direct/src/plugin/p3dFileParams.cxx @@ -89,28 +89,38 @@ set_p3d_url(const string &p3d_url) { //////////////////////////////////////////////////////////////////// // Function: P3DFileParams::set_tokens // Access: Public -// Description: Specifies the tokens associated with the instance. +// Description: Replaces all 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) { - Token token; - if (tokens[i]._keyword != NULL) { - // Make the token lowercase, since HTML is case-insensitive but - // we're not. - for (const char *p = tokens[i]._keyword; *p; ++p) { - token._keyword += tolower(*p); - } - } - if (tokens[i]._value != NULL) { - token._value = tokens[i]._value; - } - _tokens.push_back(token); + set_token(tokens[i]._keyword, tokens[i]._value); } } +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::set_token +// Access: Public +// Description: Sets an individual token value. +//////////////////////////////////////////////////////////////////// +void P3DFileParams:: +set_token(const char *keyword, const char *value) { + Token token; + if (keyword != NULL) { + // Make the token lowercase, since HTML is case-insensitive but + // we're not. + for (const char *p = keyword; *p; ++p) { + token._keyword += tolower(*p); + } + } + if (value != NULL) { + token._value = value; + } + _tokens.push_back(token); +} + //////////////////////////////////////////////////////////////////// // Function: P3DFileParams::set_args // Access: Public diff --git a/direct/src/plugin/p3dFileParams.h b/direct/src/plugin/p3dFileParams.h index 2c486d33b4..cebe1e3a6a 100644 --- a/direct/src/plugin/p3dFileParams.h +++ b/direct/src/plugin/p3dFileParams.h @@ -34,6 +34,7 @@ public: void set_p3d_offset(const int &p3d_offset); void set_p3d_url(const string &p3d_url); void set_tokens(const P3D_token tokens[], size_t num_tokens); + void set_token(const char *keyword, const char *value); void set_args(int argc, const char *argv[]); inline const string &get_p3d_filename() const; diff --git a/direct/src/plugin/p3dHost.cxx b/direct/src/plugin/p3dHost.cxx index dec72bcd64..e9155ca4d5 100644 --- a/direct/src/plugin/p3dHost.cxx +++ b/direct/src/plugin/p3dHost.cxx @@ -17,6 +17,7 @@ #include "p3dPackage.h" #include "mkdir_complete.h" #include "wstring_encode.h" +#include "xml_helpers.h" #include "openssl/md5.h" #include @@ -445,12 +446,15 @@ get_package(const string &package_name, const string &package_version, // 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. +// indicated package based on what this hardware +// supports and what is actually available. Also fills +// in per_platform, which is a boolean value indicating +// whether the directory structure contains the platform +// directory or not. //////////////////////////////////////////////////////////////////// bool P3DHost:: choose_suitable_platform(string &selected_platform, + bool &per_platform, const string &package_name, const string &package_version, const string &package_platform) { @@ -482,6 +486,7 @@ choose_suitable_platform(string &selected_platform, package_version == version) { // Here's the matching package definition. selected_platform = platform; + per_platform = parse_bool_attrib(xpackage, "per_platform", false); return true; } @@ -490,7 +495,7 @@ choose_suitable_platform(string &selected_platform, } } - // Now, we look for an exact match for the current platform. + // Now, we look for an exact match for the expected platform. xpackage = _xcontents->FirstChildElement("package"); while (xpackage != NULL) { const char *name = xpackage->Attribute("name"); @@ -505,13 +510,15 @@ choose_suitable_platform(string &selected_platform, package_version == version) { // Here's the matching package definition. selected_platform = platform; + per_platform = parse_bool_attrib(xpackage, "per_platform", false); return true; } xpackage = xpackage->NextSiblingElement("package"); } - // Look again, this time looking for a non-platform-specific version. + // Look one more time, this time looking for a non-platform-specific + // version. xpackage = _xcontents->FirstChildElement("package"); while (xpackage != NULL) { const char *name = xpackage->Attribute("name"); @@ -528,6 +535,7 @@ choose_suitable_platform(string &selected_platform, *platform == '\0' && package_version == version) { selected_platform = platform; + per_platform = parse_bool_attrib(xpackage, "per_platform", false); return true; } @@ -561,8 +569,9 @@ get_package_desc_file(FileSpec &desc_file, // out P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); - // Scan the contents data for the indicated package. First, we look - // for a platform-specific version. + // Scan the contents data for the indicated package. We expect to + // match the platform precisely, because we previously called + // choose_suitable_platform(). TiXmlElement *xpackage = _xcontents->FirstChildElement("package"); while (xpackage != NULL) { const char *name = xpackage->Attribute("name"); @@ -593,40 +602,6 @@ get_package_desc_file(FileSpec &desc_file, // out 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"); - const char *seq = xpackage->Attribute("seq"); - const char *solo = xpackage->Attribute("solo"); - if (platform == NULL) { - platform = ""; - } - if (version == NULL) { - version = ""; - } - if (seq == NULL) { - seq = ""; - } - if (name != NULL && - package_name == name && - *platform == '\0' && - package_version == version) { - // Here's the matching package definition. - desc_file.load_xml(xpackage); - package_seq = seq; - package_solo = false; - if (solo != NULL) { - package_solo = (atoi(solo) != 0); - } - return true; - } - - xpackage = xpackage->NextSiblingElement("package"); - } - // Couldn't find the named package. return false; } diff --git a/direct/src/plugin/p3dHost.h b/direct/src/plugin/p3dHost.h index 5a552d243f..b69922c3e2 100644 --- a/direct/src/plugin/p3dHost.h +++ b/direct/src/plugin/p3dHost.h @@ -58,6 +58,7 @@ public: const string &package_seq, const string &alt_host = ""); bool choose_suitable_platform(string &selected_platform, + bool &per_platform, const string &package_name, const string &package_version, const string &package_platform); diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index b9ff6c20c6..6a9c2190b5 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -1366,10 +1366,15 @@ make_xml() { xinstance->SetAttribute("log_directory", inst_mgr->get_log_directory()); xinstance->SetAttribute("verify_contents", (int)inst_mgr->get_verify_contents()); + // Tell the Panda process that it was started by a plugin that knows + // about the new per_platform flag. + xinstance->SetAttribute("respect_per_platform", 1); + if (!inst_mgr->get_super_mirror().empty()) { xinstance->SetAttribute("super_mirror", inst_mgr->get_super_mirror()); } + TiXmlElement *xfparams = _fparams.make_xml(); xinstance->LinkEndChild(xfparams); diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 1579f11fe4..0fc26caae2 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -300,6 +300,12 @@ initialize(int api_version, const string &contents_filename, } } + nout << "Supported platforms:"; + for (size_t pi = 0; pi < _supported_platforms.size(); ++pi) { + nout << " " << _supported_platforms[pi]; + } + nout << "\n"; + return true; } diff --git a/direct/src/plugin/p3dMainObject.cxx b/direct/src/plugin/p3dMainObject.cxx index e7cb8ae072..2bfbda2cf8 100644 --- a/direct/src/plugin/p3dMainObject.cxx +++ b/direct/src/plugin/p3dMainObject.cxx @@ -674,7 +674,7 @@ read_log_file(const string &log_pathname, log.seekg(0, ios::beg); log.read(buffer, full_bytes); streamsize read_bytes = log.gcount(); - assert(read_bytes < buffer_bytes); + assert(read_bytes < (streamsize)buffer_bytes); buffer[read_bytes] = '\0'; log_data << "== PandaLog-" << "Full Start"; log_data << " " << "(" << log_leafname << ")" << "\n"; @@ -688,7 +688,7 @@ read_log_file(const string &log_pathname, log.seekg(0, ios::beg); log.read(buffer, head_bytes); streamsize read_bytes = log.gcount(); - assert(read_bytes < buffer_bytes); + assert(read_bytes < (streamsize)buffer_bytes); buffer[read_bytes] = '\0'; log_data << "== PandaLog-" << "Head Start"; log_data << " " << "(" << log_leafname << ")" << "\n"; @@ -708,7 +708,7 @@ read_log_file(const string &log_pathname, log.seekg(file_size - tail_bytes, ios::beg); log.read(buffer, tail_bytes); streamsize read_bytes = log.gcount(); - assert(read_bytes < buffer_bytes); + assert(read_bytes < (streamsize)buffer_bytes); buffer[read_bytes] = '\0'; log_data << "== PandaLog-" << "Tail Start"; log_data << " " << "(" << log_leafname << ")" << "\n"; diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index 1c372393d4..2d5b327c32 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -52,10 +52,8 @@ P3DPackage(P3DHost *host, const string &package_name, _package_platform(package_platform), _alt_host(alt_host) { - _package_fullname = _package_name; - if (!_package_version.empty()) { - _package_fullname += string(".") + _package_version; - } + set_fullname(); + _per_platform = false; _patch_version = 0; // This is set true if the package is a "solo", i.e. a single @@ -638,24 +636,28 @@ host_got_contents_file() { // provided. assert(_alt_host.empty()); string new_platform; - if (_host->choose_suitable_platform(new_platform, _package_name, _package_version, _package_platform)) { + if (_host->choose_suitable_platform(new_platform, _per_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; + set_fullname(); } } else { nout << "Couldn't find a platform for " << get_package_name() << ".\n"; } + nout << "_per_platform for " << get_package_name() << " = " << _per_platform << "\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()) { + if (_per_platform && !_package_platform.empty()) { _package_dir += string("/") + _package_platform; } @@ -686,7 +688,7 @@ download_desc_file() { _package_name, _package_version, _package_platform)) { nout << "Couldn't find package " << _package_fullname - << "/" << _package_platform << " in contents file.\n"; + << " in contents file.\n"; redownload_contents_file(NULL); return; } @@ -702,8 +704,8 @@ download_desc_file() { } // The desc file might have a different path on the host server than - // it has locally, because we strip out the platform directory - // locally. + // it has locally, because we might strip out the platform directory + // locally (according to _per_platform). FileSpec local_desc_file = _desc_file; local_desc_file.set_filename(_desc_file_basename); _desc_file_pathname = local_desc_file.get_pathname(_package_dir); @@ -791,6 +793,16 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) { report_done(false); return; } + + bool per_platform = parse_bool_attrib(xpackage, "per_platform", false); + if (per_platform != _per_platform) { + nout << "Warning! per_platform disagreement for " << get_package_name() + << "!\n"; + // We don't do anything with this warning--the original value for + // _per_platform we got from the contents.xml file has to apply, + // because we're already committed to the _package_dir we're + // using. + } xpackage->Attribute("patch_version", &_patch_version); @@ -1458,6 +1470,23 @@ instance_terminating(P3DInstance *instance) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: P3DPackage::set_fullname +// Access: Private +// Description: Assigns _package_fullname to the appropriate +// combination of name, version, and platform. +//////////////////////////////////////////////////////////////////// +void P3DPackage:: +set_fullname() { + _package_fullname = _package_name; + if (!_package_version.empty()) { + _package_fullname += string(".") + _package_version; + } + if (!_package_platform.empty()) { + _package_fullname += string(".") + _package_platform; + } +} + //////////////////////////////////////////////////////////////////// // Function: P3DPackage::Download::Constructor // Access: Public diff --git a/direct/src/plugin/p3dPackage.h b/direct/src/plugin/p3dPackage.h index f280337b9f..775fda83ee 100755 --- a/direct/src/plugin/p3dPackage.h +++ b/direct/src/plugin/p3dPackage.h @@ -241,6 +241,7 @@ private: bool is_extractable(FileSpec &file, const string &filename) const; bool instance_terminating(P3DInstance *instance); + void set_fullname(); public: class RequiredPackage { @@ -264,6 +265,7 @@ private: string _package_name; string _package_version; string _package_platform; + bool _per_platform; int _patch_version; string _alt_host; bool _package_solo; diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 5bd3c7508a..a72ebdfcad 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -1252,9 +1252,12 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) { Py_INCREF(main); } + int respect_per_platform = 0; + xinstance->Attribute("respect_per_platform", &respect_per_platform); + PyObject *result = PyObject_CallMethod - (_runner, (char *)"setInstanceInfo", (char *)"sssiO", root_dir, - log_directory, super_mirror, verify_contents, main); + (_runner, (char *)"setInstanceInfo", (char *)"sssiOi", root_dir, + log_directory, super_mirror, verify_contents, main, respect_per_platform); Py_DECREF(main); if (result == NULL) { diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index 5ec430f665..d49fadc3c2 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -30,3 +30,4 @@ #include "p3dWinSplashWindow.cxx" #include "p3dX11SplashWindow.cxx" #include "p3dWindowParams.cxx" +#include "xml_helpers.cxx" diff --git a/direct/src/plugin/xml_helpers.cxx b/direct/src/plugin/xml_helpers.cxx new file mode 100755 index 0000000000..8b8b2dc3b3 --- /dev/null +++ b/direct/src/plugin/xml_helpers.cxx @@ -0,0 +1,43 @@ +// Filename: xml_helpers.cxx +// Created by: drose (28Sep12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "p3d_plugin_common.h" +#include "xml_helpers.h" + + +//////////////////////////////////////////////////////////////////// +// Function: parse_bool_attrib +// Description: Examines the indicated attrib from the XML attrib and +// returns its true or false value. Returns +// default_value if the attrib is not present or is +// empty. +//////////////////////////////////////////////////////////////////// +bool +parse_bool_attrib(TiXmlElement *xelem, const string &attrib, + bool default_value) { + const char *value = xelem->Attribute(attrib.c_str()); + if (value == NULL || *value == '\0') { + return default_value; + } + + char *endptr; + int result = strtol(value, &endptr, 10); + if (*endptr == '\0') { + // A valid integer. + return (result != 0); + } + + // An invalid integer. + return default_value; +} diff --git a/direct/src/plugin/xml_helpers.h b/direct/src/plugin/xml_helpers.h new file mode 100755 index 0000000000..022e86e9bd --- /dev/null +++ b/direct/src/plugin/xml_helpers.h @@ -0,0 +1,24 @@ +// Filename: xml_helpers.h +// Created by: drose (28Sep12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef XML_HELPERS_H +#define XML_HELPERS_H + +#include "get_tinyxml.h" + +bool parse_bool_attrib(TiXmlElement *xelem, const string &attrib, + bool default_value); + +#endif +