mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
better splash image management
This commit is contained in:
parent
f94479e13b
commit
29345bbc38
@ -138,6 +138,7 @@ class Packager:
|
||||
self.version = None
|
||||
self.host = None
|
||||
self.p3dApplication = False
|
||||
self.solo = False
|
||||
self.compressionLevel = 0
|
||||
self.importedMapsDir = 'imported_maps'
|
||||
self.mainModule = None
|
||||
@ -166,10 +167,6 @@ class Packager:
|
||||
# far.
|
||||
self.freezer = FreezeTool.Freezer()
|
||||
|
||||
# Set this true to parse and build up the internal
|
||||
# filelist, but not generate any output.
|
||||
self.dryRun = False
|
||||
|
||||
def close(self):
|
||||
""" Writes out the contents of the current package. """
|
||||
|
||||
@ -198,18 +195,46 @@ class Packager:
|
||||
# Every p3dapp requires panda3d.
|
||||
self.packager.do_require('panda3d')
|
||||
|
||||
if self.dryRun:
|
||||
self.multifile = None
|
||||
# Check to see if any of the files are platform-specific.
|
||||
platformSpecific = False
|
||||
for file in self.files:
|
||||
if file.isExcluded(self):
|
||||
# Skip this file.
|
||||
continue
|
||||
if file.platformSpecific:
|
||||
platformSpecific = True
|
||||
if platformSpecific and not self.platform:
|
||||
self.platform = PandaSystem.getPlatform()
|
||||
|
||||
if not self.p3dApplication and self.platform and not self.version:
|
||||
# We must have a version string for platform-specific
|
||||
# packages. Use the first versioned string on our
|
||||
# require list.
|
||||
self.version = 'base'
|
||||
for p2 in self.requires:
|
||||
if p2.version:
|
||||
self.version = p2.version
|
||||
break
|
||||
|
||||
if self.solo:
|
||||
self.installSolo()
|
||||
else:
|
||||
self.multifile = Multifile()
|
||||
self.installMultifile()
|
||||
|
||||
if self.p3dApplication:
|
||||
self.multifile.setHeaderPrefix('#! /usr/bin/env panda3d\n')
|
||||
def installMultifile(self):
|
||||
""" Installs the package, either as a p3d application, or
|
||||
as a true package. Either is implemented with a
|
||||
Multifile. """
|
||||
|
||||
self.multifile = Multifile()
|
||||
|
||||
# Write the multifile to a temporary filename until we
|
||||
# know enough to determine the output filename.
|
||||
multifileFilename = Filename.temporary('', self.packageName)
|
||||
self.multifile.openReadWrite(multifileFilename)
|
||||
if self.p3dApplication:
|
||||
self.multifile.setHeaderPrefix('#! /usr/bin/env panda3d\n')
|
||||
|
||||
# Write the multifile to a temporary filename until we
|
||||
# know enough to determine the output filename.
|
||||
multifileFilename = Filename.temporary('', self.packageName)
|
||||
self.multifile.openReadWrite(multifileFilename)
|
||||
|
||||
self.extracts = []
|
||||
self.components = []
|
||||
@ -306,13 +331,12 @@ class Packager:
|
||||
# Skip this file.
|
||||
continue
|
||||
|
||||
if not self.dryRun:
|
||||
if ext == 'egg' or ext == 'bam':
|
||||
# Skip model files this pass.
|
||||
pass
|
||||
else:
|
||||
# Any other file.
|
||||
self.addComponent(file)
|
||||
if ext == 'egg' or ext == 'bam':
|
||||
# Skip model files this pass.
|
||||
pass
|
||||
else:
|
||||
# Any other file.
|
||||
self.addComponent(file)
|
||||
|
||||
# Finally, now add the model files. It's important to add
|
||||
# these after we have added all of the texture files, so
|
||||
@ -331,27 +355,17 @@ class Packager:
|
||||
# Skip this file.
|
||||
continue
|
||||
|
||||
if not self.dryRun:
|
||||
if ext == 'egg':
|
||||
self.addEggFile(file)
|
||||
elif ext == 'bam':
|
||||
self.addBamFile(file)
|
||||
else:
|
||||
# Handled above.
|
||||
pass
|
||||
if ext == 'egg':
|
||||
self.addEggFile(file)
|
||||
elif ext == 'bam':
|
||||
self.addBamFile(file)
|
||||
else:
|
||||
# Handled above.
|
||||
pass
|
||||
|
||||
# Now that we've processed all of the component files,
|
||||
# (and set our platform if necessary), we can generate the
|
||||
# output filename and write the output files.
|
||||
|
||||
if not self.p3dApplication and not self.version:
|
||||
# We must have a version string for packages. Use the
|
||||
# first versioned string on our require list.
|
||||
self.version = '0.0'
|
||||
for p2 in self.requires:
|
||||
if p2.version:
|
||||
self.version = p2.version
|
||||
break
|
||||
|
||||
self.packageBasename = self.packageName
|
||||
packageDir = self.packageName
|
||||
@ -379,23 +393,63 @@ class Packager:
|
||||
self.packageFullpath.makeDir()
|
||||
self.packageFullpath.unlink()
|
||||
|
||||
if not self.dryRun:
|
||||
if self.p3dApplication:
|
||||
self.makeP3dInfo()
|
||||
self.multifile.repack()
|
||||
self.multifile.close()
|
||||
if self.p3dApplication:
|
||||
self.makeP3dInfo()
|
||||
self.multifile.repack()
|
||||
self.multifile.close()
|
||||
|
||||
multifileFilename.renameTo(self.packageFullpath)
|
||||
multifileFilename.renameTo(self.packageFullpath)
|
||||
|
||||
if self.p3dApplication:
|
||||
# Make the application file executable.
|
||||
os.chmod(self.packageFullpath.toOsSpecific(), 0755)
|
||||
else:
|
||||
self.compressMultifile()
|
||||
self.writeDescFile()
|
||||
self.writeImportDescFile()
|
||||
|
||||
if self.p3dApplication:
|
||||
# Make the application file executable.
|
||||
os.chmod(self.packageFullpath.toOsSpecific(), 0755)
|
||||
else:
|
||||
self.compressMultifile()
|
||||
self.writeDescFile()
|
||||
self.writeImportDescFile()
|
||||
|
||||
self.cleanup()
|
||||
|
||||
def installSolo(self):
|
||||
""" Installs the package as a "solo", which means we
|
||||
simply copy all files into the install directory. This is
|
||||
primarily intended for the "coreapi" plugin, which is just
|
||||
a single dll and a jpg file; but it can support other
|
||||
kinds of similar "solo" packages as well. """
|
||||
|
||||
packageDir = self.packageName
|
||||
if self.platform:
|
||||
packageDir += '/' + self.platform
|
||||
if self.version:
|
||||
packageDir += '/' + self.version
|
||||
|
||||
installPath = Filename(self.packager.installDir, packageDir)
|
||||
# Remove any files already in the installPath.
|
||||
origFiles = vfs.scanDirectory(installPath)
|
||||
if origFiles:
|
||||
for origFile in origFiles:
|
||||
origFile.getFilename().unlink()
|
||||
|
||||
if not self.files:
|
||||
# No files, never mind.
|
||||
return
|
||||
|
||||
Filename(installPath, '').makeDir()
|
||||
|
||||
for file in self.files:
|
||||
if file.isExcluded(self):
|
||||
# Skip this file.
|
||||
continue
|
||||
targetPath = Filename(installPath, file.newName)
|
||||
targetPath.setBinary()
|
||||
file.filename.setBinary()
|
||||
if not file.filename.copyTo(targetPath):
|
||||
print "Could not copy %s to %s" % (
|
||||
file.filename, targetPath)
|
||||
|
||||
self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
# Now that all the files have been packed, we can delete
|
||||
# the temporary files.
|
||||
for file in self.files:
|
||||
@ -1214,8 +1268,6 @@ class Packager:
|
||||
# A table of all known packages by name.
|
||||
self.packages = {}
|
||||
|
||||
self.dryRun = False
|
||||
|
||||
def addWindowsSearchPath(self, searchPath, varname):
|
||||
""" Expands $varname, interpreting as a Windows-style search
|
||||
path, and adds its contents to the indicated DSearchPath. """
|
||||
@ -1390,18 +1442,13 @@ class Packager:
|
||||
# side-effect that the user can put arbitrary Python code in
|
||||
# there to control conditional execution, and such.
|
||||
|
||||
# Set up the global and local dictionaries for exec.
|
||||
# Set up the namespace dictionary for exec.
|
||||
globals = {}
|
||||
globals['__name__'] = packageDef.getBasenameWoExtension()
|
||||
|
||||
globals['platform'] = PandaSystem.getPlatform()
|
||||
|
||||
# The local dictionary is initially empty, but it will be
|
||||
# filled with all the definitions at the module scope when we
|
||||
# parse the pdef file.
|
||||
locals = {}
|
||||
|
||||
# We'll stuff all of the predefined functions, and both of the
|
||||
# We'll stuff all of the predefined functions, and the
|
||||
# predefined classes, in the global dictionary, so the pdef
|
||||
# file can reference them.
|
||||
|
||||
@ -1416,23 +1463,36 @@ class Packager:
|
||||
|
||||
globals['p3d'] = class_p3d
|
||||
globals['package'] = class_package
|
||||
globals['solo'] = class_solo
|
||||
|
||||
# Now exec the pdef file. Assuming there are no syntax
|
||||
# errors, and that the pdef file doesn't contain any really
|
||||
# crazy Python code, all this will do is fill in the
|
||||
# '__statements' list in the module scope.
|
||||
execfile(packageDef.toOsSpecific(), globals, locals)
|
||||
|
||||
# It appears that having a separate globals and locals
|
||||
# dictionary causes problems with resolving symbols within a
|
||||
# class scope. So, we just use one dictionary, the globals.
|
||||
execfile(packageDef.toOsSpecific(), globals)
|
||||
|
||||
packages = []
|
||||
|
||||
# Now iterate through the statements and operate on them.
|
||||
statements = globals.get('__statements', [])
|
||||
if not statements:
|
||||
print "No packages defined."
|
||||
|
||||
try:
|
||||
for (lineno, stype, name, args, kw) in locals['__statements']:
|
||||
for (lineno, stype, name, args, kw) in statements:
|
||||
if stype == 'class':
|
||||
classDef = locals[name]
|
||||
classDef = globals[name]
|
||||
p3dApplication = (class_p3d in classDef.__bases__)
|
||||
self.beginPackage(name, p3dApplication = p3dApplication)
|
||||
statements = classDef.__dict__['__statements']
|
||||
solo = (class_solo in classDef.__bases__)
|
||||
self.beginPackage(name, p3dApplication = p3dApplication,
|
||||
solo = solo)
|
||||
statements = classDef.__dict__.get('__statements', [])
|
||||
if not statements:
|
||||
print "No files added to %s" % (name)
|
||||
for (lineno, stype, name, args, kw) in statements:
|
||||
if stype == 'class':
|
||||
raise PackagerError, 'Nested classes not allowed'
|
||||
@ -1512,22 +1572,6 @@ class Packager:
|
||||
if descriptiveName:
|
||||
self.hostDescriptiveName = descriptiveName
|
||||
|
||||
def do_modelPath(self, dirName):
|
||||
""" Specifies an additional directory that will be searched
|
||||
for required models, especially textures. Models in this
|
||||
directory are not automatically added to the package unless
|
||||
references to them are discovered; use dir() if you want to
|
||||
add an entire directory hierarchy of models. """
|
||||
|
||||
newName = None
|
||||
|
||||
try:
|
||||
command, dirName = words
|
||||
except ValueError:
|
||||
raise ArgumentError
|
||||
|
||||
getModelPath().appendDirectory(Filename.fromOsSpecific(dirName))
|
||||
|
||||
def __parseArgs(self, words, argList):
|
||||
args = {}
|
||||
|
||||
@ -1551,7 +1595,8 @@ class Packager:
|
||||
del words[-1]
|
||||
|
||||
|
||||
def beginPackage(self, packageName, p3dApplication = False):
|
||||
def beginPackage(self, packageName, p3dApplication = False,
|
||||
solo = False):
|
||||
""" Begins a new package specification. packageName is the
|
||||
basename of the package. Follow this with a number of calls
|
||||
to file() etc., and close the package with endPackage(). """
|
||||
@ -1563,7 +1608,7 @@ class Packager:
|
||||
self.currentPackage = package
|
||||
|
||||
package.p3dApplication = p3dApplication
|
||||
package.dryRun = self.dryRun
|
||||
package.solo = solo
|
||||
|
||||
def endPackage(self):
|
||||
""" Closes the current package specification. This actually
|
||||
@ -1939,20 +1984,19 @@ class Packager:
|
||||
freezer.modules[newName] = freezer.modules[moduleName]
|
||||
freezer.done(compileToExe = compileToExe)
|
||||
|
||||
if not package.dryRun:
|
||||
dirname = ''
|
||||
basename = filename
|
||||
if '/' in basename:
|
||||
dirname, basename = filename.rsplit('/', 1)
|
||||
dirname += '/'
|
||||
dirname = ''
|
||||
basename = filename
|
||||
if '/' in basename:
|
||||
dirname, basename = filename.rsplit('/', 1)
|
||||
dirname += '/'
|
||||
|
||||
basename = freezer.generateCode(basename, compileToExe = compileToExe)
|
||||
basename = freezer.generateCode(basename, compileToExe = compileToExe)
|
||||
|
||||
package.addFile(Filename(basename), newName = dirname + basename,
|
||||
deleteTemp = True, explicit = True, extract = True)
|
||||
package.addExtensionModules()
|
||||
if not package.platform:
|
||||
package.platform = PandaSystem.getPlatform()
|
||||
package.addFile(Filename(basename), newName = dirname + basename,
|
||||
deleteTemp = True, explicit = True, extract = True)
|
||||
package.addExtensionModules()
|
||||
if not package.platform:
|
||||
package.platform = PandaSystem.getPlatform()
|
||||
|
||||
# Reset the freezer for more Python files.
|
||||
freezer.reset()
|
||||
@ -1964,9 +2008,9 @@ class Packager:
|
||||
|
||||
self.addFiles(args, **kw)
|
||||
|
||||
def addFiles(self, filenames, text = None, newNameOrDir = None,
|
||||
extract = None, executable = None, deleteTemp = False,
|
||||
literal = False):
|
||||
def addFiles(self, filenames, text = None, newName = None,
|
||||
newDir = None, extract = None, executable = None,
|
||||
deleteTemp = False, literal = False):
|
||||
|
||||
""" Adds the indicated arbitrary files to the current package.
|
||||
|
||||
@ -1980,13 +2024,15 @@ class Packager:
|
||||
extension. For instance, .py files may be automatically
|
||||
compiled and stored as Python modules.
|
||||
|
||||
If newNameOrDir ends in a slash character, it specifies the
|
||||
directory in which the file should be placed. In this case,
|
||||
all files matched by the filename expression are placed in the
|
||||
named directory. If newNameOrDir ends in something other than
|
||||
a slash character, it specifies a new filename. In this case,
|
||||
the filename expression must match only one file. If
|
||||
newNameOrDir is unspecified or None, the file is placed in the
|
||||
If newDir is not None, it specifies the directory in which the
|
||||
file should be placed. In this case, all files matched by the
|
||||
filename expression are placed in the named directory.
|
||||
|
||||
If newName is not None, it specifies a new filename. In this
|
||||
case, newDir is ignored, and the filename expression must
|
||||
match only one file.
|
||||
|
||||
If newName and newDir are both None, the file is placed in the
|
||||
toplevel directory, regardless of its source directory.
|
||||
|
||||
If text is nonempty, it contains the text of the file. In
|
||||
@ -2042,17 +2088,16 @@ class Packager:
|
||||
explicit = False
|
||||
files += thisFiles
|
||||
|
||||
newName = None
|
||||
prefix = ''
|
||||
if newDir:
|
||||
prefix = Filename(newDir).cStr()
|
||||
if prefix[-1] != '/':
|
||||
prefix += '/'
|
||||
|
||||
if newNameOrDir:
|
||||
if newNameOrDir[-1] == '/':
|
||||
prefix = newNameOrDir
|
||||
else:
|
||||
newName = newNameOrDir
|
||||
if len(files) != 1:
|
||||
message = 'Cannot install multiple files on target filename %s' % (newName)
|
||||
raise PackagerError, message
|
||||
if newName:
|
||||
if len(files) != 1:
|
||||
message = 'Cannot install multiple files on target filename %s' % (newName)
|
||||
raise PackagerError, message
|
||||
|
||||
if text:
|
||||
if len(files) != 1:
|
||||
@ -2192,6 +2237,10 @@ class class_package:
|
||||
__metaclass__ = metaclass_def
|
||||
pass
|
||||
|
||||
class class_solo:
|
||||
__metaclass__ = metaclass_def
|
||||
pass
|
||||
|
||||
class func_closure:
|
||||
|
||||
""" This class is used to create a closure on the function name,
|
||||
|
@ -92,9 +92,12 @@ class ContentsMaker:
|
||||
print >> f, '<?xml version="1.0" encoding="utf-8" ?>'
|
||||
print >> f, ''
|
||||
print >> f, contentsLine
|
||||
for type, packageName, packagePlatform, packageVersion, file in self.packages:
|
||||
print >> f, ' <%s name="%s" platform="%s" version="%s" %s />' % (
|
||||
type, packageName, packagePlatform or '', packageVersion, file.getParams())
|
||||
for type, packageName, packagePlatform, packageVersion, file, solo in self.packages:
|
||||
extra = ''
|
||||
if solo:
|
||||
extra += 'solo="1" '
|
||||
print >> f, ' <%s name="%s" platform="%s" version="%s" %s%s />' % (
|
||||
type, packageName, packagePlatform or '', packageVersion or '', extra, file.getParams())
|
||||
print >> f, '</contents>'
|
||||
f.close()
|
||||
|
||||
@ -142,20 +145,23 @@ class ContentsMaker:
|
||||
localpath = dirpath[len(prefix):].replace(os.sep, '/') + '/'
|
||||
xml = dirpath[len(prefix):].replace(os.sep, '_') + '.xml'
|
||||
|
||||
type = 'package'
|
||||
solo = False
|
||||
|
||||
# A special case: the "plugin" and "coreapi" directories
|
||||
# don't have xml files, just dll's.
|
||||
if xml.startswith('plugin_') or xml.startswith('coreapi_'):
|
||||
if filenames:
|
||||
assert len(filenames) == 1
|
||||
xml = filenames[0]
|
||||
type = 'plugin'
|
||||
# A special case: if a directory contains just one file,
|
||||
# it's a "solo", not an xml package.
|
||||
if len(filenames) == 1 and not filenames[0].endswith('.xml'):
|
||||
xml = filenames[0]
|
||||
solo = True
|
||||
|
||||
if xml not in filenames:
|
||||
continue
|
||||
|
||||
if localpath.count('/') == 1:
|
||||
packageName, junk = localpath.split('/')
|
||||
packageVersion = None
|
||||
packagePlatform = None
|
||||
|
||||
if localpath.count('/') == 2:
|
||||
elif localpath.count('/') == 2:
|
||||
packageName, packageVersion, junk = localpath.split('/')
|
||||
packagePlatform = None
|
||||
|
||||
@ -167,9 +173,9 @@ class ContentsMaker:
|
||||
file = FileSpec(localpath + xml,
|
||||
os.path.join(self.installDir, localpath + xml))
|
||||
print file.filename
|
||||
self.packages.append((type, packageName, packagePlatform, packageVersion, file))
|
||||
self.packages.append(('package', packageName, packagePlatform, packageVersion, file, solo))
|
||||
|
||||
if type == 'package':
|
||||
if not solo:
|
||||
# Look for an _import.xml file, too.
|
||||
xml = xml[:-4] + '_import.xml'
|
||||
try:
|
||||
@ -179,7 +185,7 @@ class ContentsMaker:
|
||||
file = None
|
||||
if file:
|
||||
print file.filename
|
||||
self.packages.append(('import', packageName, packagePlatform, packageVersion, file))
|
||||
self.packages.append(('import', packageName, packagePlatform, packageVersion, file, False))
|
||||
|
||||
|
||||
def makeContents(args):
|
||||
|
@ -1,3 +1,5 @@
|
||||
from pandac.PandaModules import getModelPath, Filename
|
||||
|
||||
# This file defines a number of standard "packages" that correspond to
|
||||
# a Panda3D distribution. These packages are built by passing this
|
||||
# file to the ppackage utility, either as a packaged application, or
|
||||
@ -12,6 +14,19 @@
|
||||
# and then a number of smaller, optional packages, which may or may
|
||||
# not be needed by any one particular application.
|
||||
|
||||
class coreapi(solo):
|
||||
# The special "coreapi" package. As a "solo", this is just a
|
||||
# single .dll (or dylib, or whatever).
|
||||
file('p3d_plugin.dll')
|
||||
|
||||
class splash(solo):
|
||||
# We also store the default splash image, as "solo". Well, it
|
||||
# has to go somewhere.
|
||||
splashFilename = Filename('maps/panda_splash.jpg')
|
||||
if splashFilename.resolveFilename(getModelPath().getValue()):
|
||||
file(splashFilename, newName = 'splash.jpg')
|
||||
else:
|
||||
print "Could not locate %s" % (splashFilename)
|
||||
|
||||
class panda3d(package):
|
||||
# The core Panda3D package. Contains Python and most of the graphics
|
||||
|
@ -146,6 +146,7 @@ get_package(const string &package_name, const string &package_version) {
|
||||
bool P3DHost::
|
||||
get_package_desc_file(FileSpec &desc_file, // out
|
||||
string &package_platform, // out
|
||||
bool &package_solo, // out
|
||||
const string &package_name, // in
|
||||
const string &package_version) { // in
|
||||
if (_xcontents == NULL) {
|
||||
@ -161,6 +162,7 @@ get_package_desc_file(FileSpec &desc_file, // out
|
||||
const char *name = xpackage->Attribute("name");
|
||||
const char *platform = xpackage->Attribute("platform");
|
||||
const char *version = xpackage->Attribute("version");
|
||||
const char *solo = xpackage->Attribute("solo");
|
||||
if (name != NULL && platform != NULL && version != NULL &&
|
||||
package_name == name &&
|
||||
inst_mgr->get_platform() == platform &&
|
||||
@ -168,6 +170,10 @@ get_package_desc_file(FileSpec &desc_file, // out
|
||||
// Here's the matching package definition.
|
||||
desc_file.load_xml(xpackage);
|
||||
package_platform = platform;
|
||||
package_solo = false;
|
||||
if (solo != NULL) {
|
||||
package_solo = (atoi(solo) != 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -180,6 +186,7 @@ get_package_desc_file(FileSpec &desc_file, // out
|
||||
const char *name = xpackage->Attribute("name");
|
||||
const char *platform = xpackage->Attribute("platform");
|
||||
const char *version = xpackage->Attribute("version");
|
||||
const char *solo = xpackage->Attribute("solo");
|
||||
if (platform == NULL) {
|
||||
platform = "";
|
||||
}
|
||||
@ -190,6 +197,10 @@ get_package_desc_file(FileSpec &desc_file, // out
|
||||
// Here's the matching package definition.
|
||||
desc_file.load_xml(xpackage);
|
||||
package_platform = platform;
|
||||
package_solo = false;
|
||||
if (solo != NULL) {
|
||||
package_solo = (atoi(solo) != 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
const string &package_version);
|
||||
bool get_package_desc_file(FileSpec &desc_file,
|
||||
string &package_platform,
|
||||
bool &package_solo,
|
||||
const string &package_name,
|
||||
const string &package_version);
|
||||
|
||||
|
@ -61,6 +61,7 @@ P3DInstance(P3D_request_ready_func *func,
|
||||
_user_data = user_data;
|
||||
_request_pending = false;
|
||||
_temp_p3d_filename = NULL;
|
||||
_splash_package = NULL;
|
||||
_temp_splash_image = NULL;
|
||||
_got_fparams = false;
|
||||
_got_wparams = false;
|
||||
@ -121,6 +122,10 @@ P3DInstance::
|
||||
(*pi)->remove_instance(this);
|
||||
}
|
||||
_packages.clear();
|
||||
if (_splash_package != NULL) {
|
||||
_splash_package->remove_instance(this);
|
||||
_splash_package = NULL;
|
||||
}
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
delete _splash_window;
|
||||
@ -1201,32 +1206,37 @@ make_splash_window() {
|
||||
_splash_window->set_wparams(_wparams);
|
||||
_splash_window->set_install_label(_install_label);
|
||||
|
||||
string splash_image_url = _fparams.lookup_token("splash_img");
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
if (!_fparams.has_token("splash_img")) {
|
||||
// No specific splash image is specified; get the default splash
|
||||
// image.
|
||||
splash_image_url = PANDA_PACKAGE_HOST_URL;
|
||||
if (!splash_image_url.empty() && splash_image_url[splash_image_url.size() - 1] != '/') {
|
||||
splash_image_url += "/";
|
||||
// image. We do this via the P3DPackage interface, so we can
|
||||
// use the cached version on disk if it's good.
|
||||
P3DHost *host = inst_mgr->get_host(PANDA_PACKAGE_HOST_URL);
|
||||
_splash_package = host->get_package("splash", "");
|
||||
_splash_package->add_instance(this);
|
||||
|
||||
} else {
|
||||
// We have an explicit splash image specified, so just download it
|
||||
// directly. This one won't be cached locally (though the browser
|
||||
// might be free to cache it).
|
||||
string splash_image_url = _fparams.lookup_token("splash_img");
|
||||
if (splash_image_url.empty()) {
|
||||
// No splash image. Never mind.
|
||||
return;
|
||||
}
|
||||
splash_image_url += "coreapi/splash.jpg";
|
||||
|
||||
// Make a temporary file to receive the splash image.
|
||||
assert(_temp_splash_image == NULL);
|
||||
_temp_splash_image = new P3DTemporaryFile(".jpg");
|
||||
|
||||
// Start downloading the requested splash image.
|
||||
SplashDownload *download = new SplashDownload(this);
|
||||
download->set_url(splash_image_url);
|
||||
download->set_filename(_temp_splash_image->get_filename());
|
||||
|
||||
start_download(download);
|
||||
}
|
||||
|
||||
if (splash_image_url.empty()) {
|
||||
// No splash image. Never mind.
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a temporary file to receive the splash image.
|
||||
assert(_temp_splash_image == NULL);
|
||||
_temp_splash_image = new P3DTemporaryFile(".jpg");
|
||||
|
||||
// Start downloading the requested splash image.
|
||||
SplashDownload *download = new SplashDownload(this);
|
||||
download->set_url(splash_image_url);
|
||||
download->set_filename(_temp_splash_image->get_filename());
|
||||
|
||||
start_download(download);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1238,6 +1248,16 @@ make_splash_window() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
report_package_info_ready(P3DPackage *package) {
|
||||
if (package == _splash_package) {
|
||||
// A special case: we just downloaded the splash image, via the
|
||||
// package interface.
|
||||
if (_splash_window != NULL) {
|
||||
string filename = package->get_desc_file_pathname();
|
||||
_splash_window->set_image_filename(filename, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_packages_info_ready()) {
|
||||
// All packages are ready to go. Let's start some download
|
||||
// action.
|
||||
@ -1669,8 +1689,9 @@ void P3DInstance::SplashDownload::
|
||||
download_finished(bool success) {
|
||||
P3DFileDownload::download_finished(success);
|
||||
if (success) {
|
||||
// We've successfully downloaded the splash image. Put it
|
||||
// onscreen if our splash window still exists.
|
||||
// We've successfully downloaded the splash image (directly, not
|
||||
// via the package interface). Put it onscreen if our splash
|
||||
// window still exists.
|
||||
if (_inst->_splash_window != NULL) {
|
||||
_inst->_splash_window->set_image_filename(get_filename(), true);
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ private:
|
||||
P3DMainObject *_panda_script_object;
|
||||
|
||||
P3DTemporaryFile *_temp_p3d_filename;
|
||||
P3DPackage *_splash_package;
|
||||
P3DTemporaryFile *_temp_splash_image;
|
||||
|
||||
bool _got_fparams;
|
||||
|
@ -256,11 +256,6 @@ paint_window() {
|
||||
Boolean portChanged = false;
|
||||
|
||||
if (_toplevel_window != NULL) {
|
||||
/*
|
||||
GetPort(&portSave);
|
||||
SetPortWindowPort(_toplevel_window);
|
||||
BeginUpdate(_toplevel_window);
|
||||
*/
|
||||
GetPort(&out_port);
|
||||
|
||||
} else {
|
||||
|
@ -139,3 +139,16 @@ inline const string &P3DPackage::
|
||||
get_package_display_name() const {
|
||||
return _package_display_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPackage::get_desc_file_pathname
|
||||
// Access: Public
|
||||
// Description: Returns the full path to the package's desc file. If
|
||||
// this is a "solo" type package, the desc file itself
|
||||
// represents the entire contents of the package.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline const string &P3DPackage::
|
||||
get_desc_file_pathname() const {
|
||||
return _desc_file_pathname;
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,16 @@ P3DPackage(P3DHost *host, const string &package_name,
|
||||
_package_version(package_version)
|
||||
{
|
||||
_package_fullname = _package_name;
|
||||
_package_dir = _host->get_host_dir() + string("/packages/") + _package_name;
|
||||
_package_fullname += string("_") + _package_version;
|
||||
_package_dir += string("/") + _package_version;
|
||||
_package_dir = _host->get_host_dir() + string("/") + _package_name;
|
||||
|
||||
if (!_package_version.empty()) {
|
||||
_package_fullname += string("_") + _package_version;
|
||||
_package_dir += string("/") + _package_version;
|
||||
}
|
||||
|
||||
// This is set true if the package is a "solo", i.e. a single
|
||||
// file, instead of an xml file and a multifile to unpack.
|
||||
_package_solo = false;
|
||||
|
||||
_temp_contents_file = NULL;
|
||||
|
||||
@ -59,9 +66,6 @@ P3DPackage(P3DHost *host, const string &package_name,
|
||||
|
||||
// Ensure the package directory exists; create it if it does not.
|
||||
mkdir_complete(_package_dir, nout);
|
||||
|
||||
_desc_file_basename = _package_fullname + ".xml";
|
||||
_desc_file_pathname = _package_dir + "/" + _desc_file_basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -258,7 +262,8 @@ download_desc_file() {
|
||||
// exists, and is consistent with the server contents file, we don't
|
||||
// need to re-download it.
|
||||
FileSpec desc_file;
|
||||
if (!_host->get_package_desc_file(desc_file, _package_platform,
|
||||
if (!_host->get_package_desc_file(desc_file, _package_platform,
|
||||
_package_solo,
|
||||
_package_name, _package_version)) {
|
||||
nout << "Couldn't find package " << _package_fullname
|
||||
<< " in contents file.\n";
|
||||
@ -266,21 +271,33 @@ 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 locally.
|
||||
// Adjust desc_file to point to the local file.
|
||||
// it has locally, because we strip out the platform directory
|
||||
// locally. Adjust desc_file to point to the local file.
|
||||
string url_filename = desc_file.get_filename();
|
||||
|
||||
_desc_file_basename = url_filename;
|
||||
size_t slash = _desc_file_basename.rfind('/');
|
||||
if (slash != string::npos) {
|
||||
_desc_file_basename = _desc_file_basename.substr(slash + 1);
|
||||
}
|
||||
desc_file.set_filename(_desc_file_basename);
|
||||
assert (desc_file.get_pathname(_package_dir) == _desc_file_pathname);
|
||||
_desc_file_pathname = desc_file.get_pathname(_package_dir);
|
||||
|
||||
if (!desc_file.full_verify(_package_dir)) {
|
||||
nout << _desc_file_pathname << " is stale.\n";
|
||||
|
||||
} else {
|
||||
// The desc file is current. Attempt to read it.
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (doc.LoadFile()) {
|
||||
got_desc_file(&doc, false);
|
||||
if (_package_solo) {
|
||||
// No need to load it: the desc file *is* the package.
|
||||
report_done(true);
|
||||
return;
|
||||
} else {
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (doc.LoadFile()) {
|
||||
got_desc_file(&doc, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,14 +320,21 @@ desc_file_download_finished(bool success) {
|
||||
return;
|
||||
}
|
||||
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (!doc.LoadFile()) {
|
||||
nout << "Couldn't read " << _desc_file_pathname << "\n";
|
||||
report_done(false);
|
||||
if (_package_solo) {
|
||||
// No need to load it: the desc file *is* the package.
|
||||
report_done(true);
|
||||
return;
|
||||
}
|
||||
|
||||
got_desc_file(&doc, true);
|
||||
} else {
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (!doc.LoadFile()) {
|
||||
nout << "Couldn't read " << _desc_file_pathname << "\n";
|
||||
report_done(false);
|
||||
return;
|
||||
}
|
||||
|
||||
got_desc_file(&doc, true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
inline const string &get_package_version() const;
|
||||
inline const string &get_package_display_name() const;
|
||||
|
||||
inline const string &get_desc_file_pathname() const;
|
||||
|
||||
void add_instance(P3DInstance *inst);
|
||||
void remove_instance(P3DInstance *inst);
|
||||
|
||||
@ -112,6 +114,7 @@ private:
|
||||
string _package_name;
|
||||
string _package_version;
|
||||
string _package_platform;
|
||||
bool _package_solo;
|
||||
string _package_display_name;
|
||||
string _package_fullname;
|
||||
string _package_dir;
|
||||
|
@ -735,23 +735,23 @@ read_contents_file(const string &contents_filename) {
|
||||
|
||||
TiXmlElement *xcontents = doc.FirstChildElement("contents");
|
||||
if (xcontents != NULL) {
|
||||
TiXmlElement *xplugin = xcontents->FirstChildElement("plugin");
|
||||
while (xplugin != NULL) {
|
||||
const char *name = xplugin->Attribute("name");
|
||||
TiXmlElement *xpackage = xcontents->FirstChildElement("package");
|
||||
while (xpackage != NULL) {
|
||||
const char *name = xpackage->Attribute("name");
|
||||
if (name != NULL && strcmp(name, "coreapi") == 0) {
|
||||
const char *platform = xplugin->Attribute("platform");
|
||||
const char *platform = xpackage->Attribute("platform");
|
||||
if (platform != NULL && strcmp(platform, DTOOL_PLATFORM) == 0) {
|
||||
get_core_api(xplugin);
|
||||
get_core_api(xpackage);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
xplugin = xplugin->NextSiblingElement("plugin");
|
||||
xpackage = xpackage->NextSiblingElement("package");
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find the coreapi plugin description.
|
||||
nout << "No coreapi plugin defined in contents file for "
|
||||
// Couldn't find the coreapi package description.
|
||||
nout << "No coreapi package defined in contents file for "
|
||||
<< DTOOL_PLATFORM << "\n";
|
||||
return false;
|
||||
}
|
||||
@ -851,8 +851,8 @@ feed_file(PPDownloadRequest *req, const string &filename) {
|
||||
// if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
get_core_api(TiXmlElement *xplugin) {
|
||||
_core_api_dll.load_xml(xplugin);
|
||||
get_core_api(TiXmlElement *xpackage) {
|
||||
_core_api_dll.load_xml(xpackage);
|
||||
|
||||
if (_core_api_dll.quick_verify(_root_dir)) {
|
||||
// The DLL file is good. Just load it.
|
||||
|
@ -72,7 +72,7 @@ private:
|
||||
void feed_file(PPDownloadRequest *req, const string &filename);
|
||||
|
||||
bool read_contents_file(const string &contents_filename);
|
||||
void get_core_api(TiXmlElement *xplugin);
|
||||
void get_core_api(TiXmlElement *xpackage);
|
||||
void downloaded_plugin(const string &filename);
|
||||
void do_load_plugin();
|
||||
|
||||
|
@ -394,18 +394,18 @@ read_contents_file(Filename contents_filename, const string &download_url,
|
||||
|
||||
TiXmlElement *xcontents = doc.FirstChildElement("contents");
|
||||
if (xcontents != NULL) {
|
||||
TiXmlElement *xplugin = xcontents->FirstChildElement("plugin");
|
||||
while (xplugin != NULL) {
|
||||
const char *name = xplugin->Attribute("name");
|
||||
TiXmlElement *xpackage = xcontents->FirstChildElement("package");
|
||||
while (xpackage != NULL) {
|
||||
const char *name = xpackage->Attribute("name");
|
||||
if (name != NULL && strcmp(name, "coreapi") == 0) {
|
||||
const char *xplatform = xplugin->Attribute("platform");
|
||||
const char *xplatform = xpackage->Attribute("platform");
|
||||
if (xplatform != NULL && strcmp(xplatform, this_platform.c_str()) == 0) {
|
||||
return get_core_api(contents_filename, download_url,
|
||||
this_platform, verify_contents, xplugin);
|
||||
this_platform, verify_contents, xpackage);
|
||||
}
|
||||
}
|
||||
|
||||
xplugin = xplugin->NextSiblingElement("plugin");
|
||||
xpackage = xpackage->NextSiblingElement("package");
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,8 +426,8 @@ read_contents_file(Filename contents_filename, const string &download_url,
|
||||
bool Panda3D::
|
||||
get_core_api(const Filename &contents_filename, const string &download_url,
|
||||
const string &this_platform, bool verify_contents,
|
||||
TiXmlElement *xplugin) {
|
||||
_core_api_dll.load_xml(xplugin);
|
||||
TiXmlElement *xpackage) {
|
||||
_core_api_dll.load_xml(xpackage);
|
||||
|
||||
if (!_core_api_dll.quick_verify(_root_dir)) {
|
||||
// The DLL file needs to be downloaded. Go get it.
|
||||
|
Loading…
x
Reference in New Issue
Block a user