From 2dbd154536514522cece5c7ad711687c7caea360 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 22 Oct 2009 07:05:51 +0000 Subject: [PATCH] better handling of some startup failures; don't make a osx gui app unless necessary --- direct/src/p3d/AppRunner.py | 43 +++++++++++++++++++++-------- direct/src/p3d/PackageInfo.py | 8 +++++- direct/src/p3d/panda3d.pdef | 2 ++ direct/src/plugin/p3dPythonMain.cxx | 15 ---------- direct/src/plugin/p3dPythonRun.cxx | 21 ++++++++------ direct/src/showbase/ShowBase.py | 2 ++ direct/src/showbase/showBase.cxx | 22 +++++++++++++++ direct/src/showbase/showBase.h | 2 +- 8 files changed, 78 insertions(+), 37 deletions(-) diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index fa11cceaa6..2cd47fa762 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -33,7 +33,7 @@ else: from direct.showbase import VFSImporter from direct.showbase.DirectObject import DirectObject -from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, Thread, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString +from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, Thread, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString, initAppForGui from pandac import PandaModules from direct.stdpy import file from direct.task.TaskManagerGlobal import taskMgr @@ -80,6 +80,7 @@ class AppRunner(DirectObject): # These will be set from the application flags when # setP3DFilename() is called. self.allowPythonDev = False + self.guiApp = False self.interactiveConsole = False self.initialAppImport = False @@ -518,29 +519,41 @@ class AppRunner(DirectObject): self.superMirrorUrl = superMirrorUrl def addPackageInfo(self, name, platform, version, hostUrl): - """ Called by the browser to list all of the "required" - packages that were preloaded before starting the - application. If for some reason the package isn't already - downloaded, this will download it on the spot. """ + """ Called by the browser for each one of the "required" + packages that were preloaded before starting the application. + If for some reason the package isn't already downloaded, this + will download it on the spot. Raises OSError on failure. """ host = self.getHost(hostUrl) if not host.readContentsFile(): if not host.downloadContentsFile(self.http): - print "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name) - return + message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name) + raise OSError, message if not platform: platform = None package = host.getPackage(name, version, platform = platform) if not package: - print "Couldn't find %s %s on %s" % (name, version, hostUrl) - return + message = "Couldn't find %s %s on %s" % (name, version, hostUrl) + raise OSError, message package.checkStatus() - package.downloadDescFile(self.http) - package.downloadPackage(self.http) - package.installPackage(self) + if not package.downloadDescFile(self.http): + message = "Couldn't get desc file for %s" % (name) + raise OSError, message + + if not package.downloadPackage(self.http): + message = "Couldn't download %s" % (name) + raise OSError, message + + if not package.installPackage(self): + message = "Couldn't install %s" % (name) + raise OSError, message + + if package.guiApp: + self.guiApp = True + initAppForGui() def setP3DFilename(self, p3dFilename, tokens, argv, instanceId, interactiveConsole): @@ -608,6 +621,9 @@ class AppRunner(DirectObject): allowPythonDev = self.p3dConfig.Attribute('allow_python_dev') if allowPythonDev: self.allowPythonDev = int(allowPythonDev) + guiApp = self.p3dConfig.Attribute('gui_app') + if guiApp: + self.guiApp = int(guiApp) xhost = self.p3dConfig.FirstChildElement('host') while xhost: @@ -625,6 +641,9 @@ class AppRunner(DirectObject): # allow_python_dev is enabled. ConfigVariableString('frame-rate-meter-text-pattern').setValue('allow_python_dev %0.1f fps') + if self.guiApp: + initAppForGui() + self.initPackedAppEnvironment() # Mount the Multifile under /mf, by convention. diff --git a/direct/src/p3d/PackageInfo.py b/direct/src/p3d/PackageInfo.py index 6d23390907..c183366150 100644 --- a/direct/src/p3d/PackageInfo.py +++ b/direct/src/p3d/PackageInfo.py @@ -77,6 +77,7 @@ class PackageInfo: self.hasDescFile = False self.patchVersion = None self.displayName = None + self.guiApp = False self.uncompressedArchive = None self.compressedArchive = None self.extracts = [] @@ -243,6 +244,11 @@ class PackageInfo: # The name for display to an English-speaking user. self.displayName = xconfig.Attribute('display_name') + # True if any apps that use this package must be GUI apps. + guiApp = xconfig.Attribute('gui_app') + if guiApp: + self.guiApp = int(guiApp) + # The uncompressed archive, which will be mounted directly, # and also used for patching. xuncompressedArchive = xpackage.FirstChildElement('uncompressed_archive') @@ -800,7 +806,7 @@ class PackageInfo: def installPackage(self, appRunner): """ Mounts the package and sets up system paths so it becomes - available for use. """ + available for use. Returns true on success, false on failure. """ assert self.hasPackage if self.installed: diff --git a/direct/src/p3d/panda3d.pdef b/direct/src/p3d/panda3d.pdef index 19c726fed7..25421660e8 100755 --- a/direct/src/p3d/panda3d.pdef +++ b/direct/src/p3d/panda3d.pdef @@ -214,6 +214,7 @@ class ode(package): class wx(package): config(display_name = "wxPython GUI Toolkit") + config(gui_app = True) require('panda3d') module('direct.showbase.WxGlobal', 'wx', 'wx.*') @@ -221,6 +222,7 @@ class wx(package): class tk(package): config(display_name = "Tk GUI Toolkit") + config(gui_app = True) require('panda3d') module('Tkinter', diff --git a/direct/src/plugin/p3dPythonMain.cxx b/direct/src/plugin/p3dPythonMain.cxx index 347e6f56fb..bf218a8cb9 100644 --- a/direct/src/plugin/p3dPythonMain.cxx +++ b/direct/src/plugin/p3dPythonMain.cxx @@ -20,11 +20,6 @@ #include #include // strrchr using namespace std; - -#ifdef __APPLE__ -#include -extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } -#endif #if defined(_WIN32) && defined(NON_CONSOLE) // On Windows, we may need to build p3dpythonw.exe, a non-console @@ -155,16 +150,6 @@ main(int argc, char *argv[]) { } } -#ifdef __APPLE__ - // In case the application is going to run a wx app, allow it to - // have access to the desktop. - ProcessSerialNumber psn; - - GetCurrentProcess(&psn); - CPSEnableForegroundOperation(&psn); - SetFrontProcess(&psn); -#endif - if (!run_p3dpython(program_name, archive_file, input_handle, output_handle, NULL, interactive_console)) { cerr << "Failure on startup.\n"; diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 5524a9395b..09592d9e7c 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -1180,9 +1180,10 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) { if (result == NULL) { PyErr_Print(); - if (!_interactive_console) { - exit(1); + if (_interactive_console) { + run_interactive_console(); } + exit(1); } Py_XDECREF(result); } @@ -1214,10 +1215,12 @@ add_package_info(P3DCInstance *inst, TiXmlElement *xpackage) { if (result == NULL) { PyErr_Print(); - if (!_interactive_console) { - exit(1); + if (_interactive_console) { + run_interactive_console(); } + exit(1); } + Py_XDECREF(result); } @@ -1281,9 +1284,10 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) { if (result == NULL) { PyErr_Print(); - if (!_interactive_console) { - exit(1); + if (_interactive_console) { + run_interactive_console(); } + exit(1); } Py_XDECREF(result); } @@ -1380,9 +1384,10 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) { if (result == NULL) { PyErr_Print(); - if (!_interactive_console) { - exit(1); + if (_interactive_console) { + run_interactive_console(); } + exit(1); } Py_XDECREF(result); } diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 0a4ae9f0c5..ba098b742a 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -2429,6 +2429,7 @@ class ShowBase(DirectObject.DirectObject): def startWx(self, fWantWx = 1): self.wantWx = fWantWx if self.wantWx: + initAppForGui() from direct.showbase import WxGlobal taskMgr.remove('wxLoop') WxGlobal.spawnWxLoop() @@ -2436,6 +2437,7 @@ class ShowBase(DirectObject.DirectObject): def startTk(self, fWantTk = 1): self.wantTk = fWantTk if self.wantTk: + initAppForGui() from direct.showbase import TkGlobal taskMgr.remove('tkLoop') TkGlobal.spawnTkLoop() diff --git a/direct/src/showbase/showBase.cxx b/direct/src/showbase/showBase.cxx index 4dc737edf2..b7b5b94006 100644 --- a/direct/src/showbase/showBase.cxx +++ b/direct/src/showbase/showBase.cxx @@ -19,6 +19,11 @@ #include "renderBuffer.h" #include "camera.h" #include "graphicsPipeSelection.h" + +#ifdef __APPLE__ +#include +extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } +#endif #ifdef WIN32 #include // For SystemParametersInfo() @@ -55,6 +60,23 @@ get_config_showbase() { return config_showbase; } +// Initialize the application for making a Gui-based app, such as wx. +// At the moment, this is a no-op except on Mac. +void +init_app_for_gui() { + static bool initted_for_gui = false; + if (!initted_for_gui) { + initted_for_gui = true; +#ifdef IS_OSX + ProcessSerialNumber psn; + + GetCurrentProcess(&psn); + CPSEnableForegroundOperation(&psn); + SetFrontProcess(&psn); +#endif // IS_OSX + } +} + // klunky interface since we cant pass array from python->C++ to use verify_window_sizes directly static int num_fullscreen_testsizes = 0; #define MAX_FULLSCREEN_TESTS 10 diff --git a/direct/src/showbase/showBase.h b/direct/src/showbase/showBase.h index 132d853942..68c2667682 100644 --- a/direct/src/showbase/showBase.h +++ b/direct/src/showbase/showBase.h @@ -40,7 +40,7 @@ EXPCL_DIRECT ConfigVariableSearchPath &get_particle_path(); EXPCL_DIRECT void throw_new_frame(); EXPCL_DIRECT DConfig &get_config_showbase(); - +EXPCL_DIRECT void init_app_for_gui(); // klunky interface since we cant pass array from python->C++ EXPCL_DIRECT void add_fullscreen_testsize(int xsize, int ysize);