better handling of some startup failures; don't make a osx gui app unless necessary

This commit is contained in:
David Rose 2009-10-22 07:05:51 +00:00
parent 3f5dd0d039
commit 2dbd154536
8 changed files with 78 additions and 37 deletions

View File

@ -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.

View File

@ -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:

View File

@ -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',

View File

@ -20,11 +20,6 @@
#include <assert.h>
#include <string.h> // strrchr
using namespace std;
#ifdef __APPLE__
#include <Carbon/Carbon.h>
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";

View File

@ -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);
}

View File

@ -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()

View File

@ -19,6 +19,11 @@
#include "renderBuffer.h"
#include "camera.h"
#include "graphicsPipeSelection.h"
#ifdef __APPLE__
#include <Carbon/Carbon.h>
extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); }
#endif
#ifdef WIN32
#include <windows.h> // 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

View File

@ -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);