From 77552be22a75ed17385e8ea112a287b8c8e53321 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 24 Mar 2011 20:56:22 +0000 Subject: [PATCH] fix failure to run p3d file from cache without internet connection --- direct/src/p3d/AppRunner.py | 11 ++++++++++- direct/src/p3d/Packager.py | 26 +++++++++++++++++++++++++- direct/src/plugin/p3dHost.I | 20 ++++++++++++++++++-- direct/src/plugin/p3dHost.h | 1 + direct/src/plugin/p3dPackage.cxx | 19 ++++++++++++++----- 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index e616d615d0..64c977922b 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -824,8 +824,17 @@ class AppRunner(DirectObject): host.readContentsFile() if not host.downloadContentsFile(self.http): + # Couldn't download? Must have failed to download in the + # plugin as well. But since we launched, we probably have + # a copy already local; let's use it. message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name) - raise OSError, message + if not host.hasContentsFile: + # This is weird. How did we launch without having + # this file at all? + raise OSError, message + + # Just make it a warning and continue. + self.notify.warning(message) if name == 'panda3d' and not self.pandaHostUrl: # A special case: in case we don't have the PackageHostUrl diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index 54fd59bc3d..8b0a7bfc3b 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -413,7 +413,10 @@ class Packager: # Every p3dapp requires panda3d. if 'panda3d' not in map(lambda p: p.packageName, self.requires): + assert not self.packager.currentPackage + self.packager.currentPackage = self self.packager.do_require('panda3d') + self.packager.currentPackage = None # If this flag is set, enable allow_python_dev. if self.packager.allowPythonDev: @@ -1605,6 +1608,9 @@ class Packager: self.packageSeq.storeXml(xpackage, 'seq') self.packageSetVer.storeXml(xpackage, 'set_ver') + requireHosts = {} + requireHosts[self.host] = True + for package in self.requires: xrequires = TiXmlElement('requires') xrequires.SetAttribute('name', package.packageName) @@ -1612,11 +1618,20 @@ class Packager: xrequires.SetAttribute('platform', package.platform) if package.version: xrequires.SetAttribute('version', package.version) + xrequires.SetAttribute('host', package.host) package.packageSeq.storeXml(xrequires, 'seq') package.packageSetVer.storeXml(xrequires, 'set_ver') - xrequires.SetAttribute('host', package.host) + requireHosts[package.host] = True xpackage.InsertEndChild(xrequires) + # Make sure we also write the full host descriptions for + # any hosts we reference, so we can find these guys later. + for host in requireHosts.keys(): + he = self.packager.hosts.get(host, None) + if he: + xhost = he.makeXml(packager = self.packager) + xpackage.InsertEndChild(xhost) + self.components.sort() for type, name, xcomponent in self.components: xpackage.InsertEndChild(xcomponent) @@ -1643,6 +1658,15 @@ class Packager: self.version = xpackage.Attribute('version') self.host = xpackage.Attribute('host') + # Get any new host descriptors. + xhost = xpackage.FirstChildElement('host') + while xhost: + he = self.packager.HostEntry() + he.loadXml(xhost, self) + if he.url not in self.packager.hosts: + self.packager.hosts[he.url] = he + xhost = xhost.NextSiblingElement('host') + self.packageSeq.loadXml(xpackage, 'seq') self.packageSetVer.loadXml(xpackage, 'set_ver') diff --git a/direct/src/plugin/p3dHost.I b/direct/src/plugin/p3dHost.I index 974eebb04a..3adad28e98 100644 --- a/direct/src/plugin/p3dHost.I +++ b/direct/src/plugin/p3dHost.I @@ -13,15 +13,31 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: P3DHost::has_host_dir +// Access: Public +// Description: Returns true if the host_dir has already been set, +// false if not. If this returns true it is safe to +// call get_host_dir(). +//////////////////////////////////////////////////////////////////// +inline bool P3DHost:: +has_host_dir() const { + return (!_host_dir.empty()); +} + //////////////////////////////////////////////////////////////////// // Function: P3DHost::get_host_dir // Access: Public // Description: Returns the local directory into which files -// downloaded from this host will be installed. +// downloaded from this host will be installed. It may +// not be safe to call this before the host has fully +// bootstrapped; if there is some danger of calling this +// early in the initialization process, you should check +// has_host_dir() first. //////////////////////////////////////////////////////////////////// inline const string &P3DHost:: get_host_dir() const { - assert(!_host_dir.empty()); + assert(has_host_dir()); return _host_dir; } diff --git a/direct/src/plugin/p3dHost.h b/direct/src/plugin/p3dHost.h index 7b943fe84d..64bca8e17e 100644 --- a/direct/src/plugin/p3dHost.h +++ b/direct/src/plugin/p3dHost.h @@ -34,6 +34,7 @@ private: ~P3DHost(); public: + inline bool has_host_dir() const; inline const string &get_host_dir() const; inline const string &get_host_url() const; inline const string &get_host_url_prefix() const; diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index 5604b1a336..541c259217 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -446,11 +446,20 @@ contents_file_download_finished(bool success) { } // Maybe we can read an already-downloaded contents.xml file. - string standard_filename = _host->get_host_dir() + "/contents.xml"; - if (_host->get_host_dir().empty() || - !_host->read_contents_file(standard_filename, false)) { - // Couldn't even read that. Fail. - nout << "Couldn't read " << standard_filename << "\n"; + bool success = false; + if (_host->has_host_dir()) { + string standard_filename = _host->get_host_dir() + "/contents.xml"; + if (_host->read_contents_file(standard_filename, false)) { + success = true; + } else { + nout << "Couldn't read " << standard_filename << "\n"; + } + } else { + nout << "No host_dir available for " << _host->get_host_url() + << "\n"; + } + if (!success) { + // Couldn't read an already-downloaded file either. Fail. report_done(false); if (_temp_contents_file) { delete _temp_contents_file;