mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
better failed-case handling
This commit is contained in:
parent
36d8b7c0f0
commit
9ecc675b72
@ -26,7 +26,7 @@ class coreapi(solo):
|
||||
|
||||
class images(package):
|
||||
# The default startup images are stored as their own package.
|
||||
names = ['download', 'play_click', 'play_ready', 'play_rollover',
|
||||
names = ['download', 'failed', 'play_click', 'play_ready', 'play_rollover',
|
||||
'auth_click', 'auth_ready', 'auth_rollover']
|
||||
configDict = {}
|
||||
for name in names:
|
||||
@ -55,13 +55,12 @@ class images(package):
|
||||
print "Could not locate %s" % (filename)
|
||||
|
||||
# Also make a few special cases. We use the same default image
|
||||
# for download, ready, unauth, launch, and failed.
|
||||
# for download, ready, unauth, and launch.
|
||||
download = configDict.get('download_img', None)
|
||||
if download:
|
||||
configDict['ready_img'] = download
|
||||
configDict['unauth_img'] = download
|
||||
configDict['launch_img'] = download
|
||||
configDict['failed_img'] = download
|
||||
|
||||
config(**configDict)
|
||||
|
||||
|
@ -156,6 +156,7 @@ audio-library-name miles_audio
|
||||
class audio(package):
|
||||
# This package includes the best audio library for the given
|
||||
# platform, assuming a non-commercial application.
|
||||
require('panda3d')
|
||||
|
||||
if platform.startswith('osx'):
|
||||
require('fmod')
|
||||
|
@ -107,6 +107,17 @@ is_started() const {
|
||||
return (_session != NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::is_failed
|
||||
// Access: Public
|
||||
// Description: Returns true if this instance has tried and failed to
|
||||
// launch for some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool P3DInstance::
|
||||
is_failed() const {
|
||||
return _failed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::ImageFile::Constructor
|
||||
// Access: Public
|
||||
|
@ -93,11 +93,13 @@ P3DInstance(P3D_request_ready_func *func,
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
_instance_id = inst_mgr->get_unique_id();
|
||||
_has_log_basename = false;
|
||||
_hidden = (_fparams.lookup_token_int("hidden") != 0);
|
||||
_allow_python_dev = false;
|
||||
_keep_user_env = false;
|
||||
_auto_start = false;
|
||||
_auth_button_approved = false;
|
||||
_failed = false;
|
||||
_session = NULL;
|
||||
_auth_session = NULL;
|
||||
_panda3d = NULL;
|
||||
@ -320,6 +322,7 @@ set_p3d_filename(const string &p3d_filename) {
|
||||
|
||||
if (!_mf_reader.open_read(_fparams.get_p3d_filename())) {
|
||||
nout << "Couldn't read " << _fparams.get_p3d_filename() << "\n";
|
||||
set_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1189,6 +1192,9 @@ void P3DInstance::
|
||||
mark_p3d_untrusted() {
|
||||
// Failed test.
|
||||
nout << "p3d untrusted\n";
|
||||
if (is_failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_p3dcert_package == NULL) {
|
||||
// We have to go download this package.
|
||||
@ -1238,7 +1244,7 @@ mark_p3d_trusted() {
|
||||
stringstream sstream;
|
||||
if (!_mf_reader.extract_one(sstream, "p3d_info.xml")) {
|
||||
nout << "No p3d_info.xml file found in " << _fparams.get_p3d_filename() << "\n";
|
||||
// TODO: fail.
|
||||
set_failed();
|
||||
|
||||
} else {
|
||||
sstream.seekg(0);
|
||||
@ -1296,8 +1302,10 @@ scan_app_desc_file(TiXmlDocument *doc) {
|
||||
_xpackage = (TiXmlElement *)xpackage->Clone();
|
||||
|
||||
const char *log_basename = _xpackage->Attribute("log_basename");
|
||||
_has_log_basename = false;
|
||||
if (log_basename != NULL) {
|
||||
_log_basename = log_basename;
|
||||
_has_log_basename = false;
|
||||
}
|
||||
|
||||
TiXmlElement *xconfig = _xpackage->FirstChildElement("config");
|
||||
@ -1675,6 +1683,21 @@ handle_script_request(const string &operation, P3D_object *object,
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::set_failed
|
||||
// Access: Private
|
||||
// Description: Sets the "failed" indication to display sadness to
|
||||
// the user--we're unable to launch the instance for
|
||||
// some reason.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
set_failed() {
|
||||
_failed = true;
|
||||
set_button_image(IT_none);
|
||||
set_background_image(IT_failed);
|
||||
make_splash_window();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::make_splash_window
|
||||
// Access: Private
|
||||
@ -1698,6 +1721,12 @@ make_splash_window() {
|
||||
make_visible = false;
|
||||
}
|
||||
|
||||
if (_failed) {
|
||||
// But, if we've failed to launch somehow, we need to let the user
|
||||
// know.
|
||||
make_visible = true;
|
||||
}
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
// Already got one.
|
||||
_splash_window->set_visible(make_visible);
|
||||
@ -1929,7 +1958,7 @@ start_next_download() {
|
||||
while (_download_package_index < (int)_downloading_packages.size()) {
|
||||
P3DPackage *package = _downloading_packages[_download_package_index];
|
||||
if (package->get_failed()) {
|
||||
// Too bad. TODO: fail.
|
||||
set_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2001,8 +2030,8 @@ mark_download_complete() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
ready_to_start() {
|
||||
if (is_started()) {
|
||||
// Already started.
|
||||
if (is_started() || is_failed()) {
|
||||
// Already started--or never mind.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2160,7 +2189,7 @@ report_package_done(P3DPackage *package, bool success) {
|
||||
report_package_progress(package, 1.0);
|
||||
start_next_download();
|
||||
} else {
|
||||
// TODO: fail.
|
||||
set_failed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
inline bool is_trusted() const;
|
||||
void start_download(P3DDownload *download);
|
||||
inline bool is_started() const;
|
||||
inline bool is_failed() const;
|
||||
void request_stop_sub_thread();
|
||||
void request_stop_main_thread();
|
||||
void request_refresh();
|
||||
@ -164,6 +165,7 @@ private:
|
||||
const string &property_name, P3D_object *value,
|
||||
bool needs_response, int unique_id);
|
||||
|
||||
void set_failed();
|
||||
void make_splash_window();
|
||||
void set_background_image(ImageType image_type);
|
||||
void set_button_image(ImageType image_type);
|
||||
@ -226,11 +228,13 @@ private:
|
||||
int _instance_id;
|
||||
string _session_key;
|
||||
string _log_basename;
|
||||
bool _has_log_basename;
|
||||
bool _hidden;
|
||||
bool _allow_python_dev;
|
||||
bool _keep_user_env;
|
||||
bool _auto_start;
|
||||
bool _auth_button_approved;
|
||||
bool _failed;
|
||||
|
||||
P3DSession *_session;
|
||||
P3DAuthSession *_auth_session;
|
||||
|
@ -222,17 +222,18 @@ initialize(const string &contents_filename, const string &host_url,
|
||||
_log_basename = P3D_PLUGIN_LOG_BASENAME2;
|
||||
}
|
||||
#endif
|
||||
if (!_log_basename.empty()) {
|
||||
_log_pathname = _log_directory;
|
||||
_log_pathname += _log_basename;
|
||||
_log_pathname += ".log";
|
||||
|
||||
logfile.clear();
|
||||
logfile.open(_log_pathname.c_str(), ios::out | ios::trunc);
|
||||
if (logfile) {
|
||||
logfile.setf(ios::unitbuf);
|
||||
nout_stream = &logfile;
|
||||
}
|
||||
if (_log_basename.empty()) {
|
||||
_log_basename = "p3dcore";
|
||||
}
|
||||
_log_pathname = _log_directory;
|
||||
_log_pathname += _log_basename;
|
||||
_log_pathname += ".log";
|
||||
|
||||
logfile.clear();
|
||||
logfile.open(_log_pathname.c_str(), ios::out | ios::trunc);
|
||||
if (logfile) {
|
||||
logfile.setf(ios::unitbuf);
|
||||
nout_stream = &logfile;
|
||||
}
|
||||
|
||||
// Determine the temporary directory.
|
||||
@ -434,6 +435,11 @@ set_p3d_filename(P3DInstance *inst, bool is_local,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DInstanceManager::
|
||||
start_instance(P3DInstance *inst) {
|
||||
if (inst->is_failed()) {
|
||||
// Don't bother trying again.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inst->is_started()) {
|
||||
// Already started.
|
||||
return true;
|
||||
|
@ -90,6 +90,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
EventTypeSpec list1[] = {
|
||||
{ kEventClassWindow, kEventWindowDrawContent },
|
||||
{ kEventClassWindow, kEventWindowBoundsChanged },
|
||||
{ kEventClassWindow, kEventWindowClose },
|
||||
{ kEventClassMouse, kEventMouseUp },
|
||||
{ kEventClassMouse, kEventMouseDown },
|
||||
{ kEventClassMouse, kEventMouseMoved },
|
||||
@ -605,6 +606,12 @@ event_callback(EventHandlerCallRef my_handler, EventRef event) {
|
||||
|
||||
case kEventWindowDrawContent:
|
||||
paint_window();
|
||||
break;
|
||||
|
||||
case kEventWindowClose:
|
||||
// When the user closes the splash window, stop the instance.
|
||||
_inst->request_stop_sub_thread();
|
||||
break;
|
||||
};
|
||||
break;
|
||||
|
||||
|
@ -56,6 +56,8 @@ P3DSession(P3DInstance *inst) {
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
_session_id = inst_mgr->get_unique_id();
|
||||
_session_key = inst->get_session_key();
|
||||
_keep_user_env = false;
|
||||
_failed = false;
|
||||
|
||||
_start_dir = inst_mgr->get_root_dir() + "/start";
|
||||
_p3dpython_one_process = false;
|
||||
@ -214,6 +216,10 @@ void P3DSession::
|
||||
start_instance(P3DInstance *inst) {
|
||||
assert(inst->_session == NULL);
|
||||
assert(inst->get_session_key() == _session_key);
|
||||
if (_failed) {
|
||||
inst->set_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
inst->ref();
|
||||
ACQUIRE_LOCK(_instances_lock);
|
||||
@ -342,6 +348,7 @@ command_and_response(TiXmlDocument *command) {
|
||||
// in recursively.
|
||||
_response_ready.release();
|
||||
Instances::iterator ii;
|
||||
// TODO: should we acquire _instances_lock? Deadlock concerns?
|
||||
for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
|
||||
P3DInstance *inst = (*ii).second;
|
||||
inst->bake_requests();
|
||||
@ -678,6 +685,7 @@ start_p3dpython(P3DInstance *inst) {
|
||||
|
||||
if (inst->_panda3d == NULL) {
|
||||
nout << "Couldn't start Python: no panda3d dependency.\n";
|
||||
set_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -823,7 +831,7 @@ start_p3dpython(P3DInstance *inst) {
|
||||
const char *dont_keep[] = {
|
||||
"PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH",
|
||||
"PYTHONPATH", "PYTHONHOME", "PRC_PATH", "PANDA_PRC_PATH",
|
||||
"TEMP",
|
||||
"TEMP", "CTPROJS",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -931,19 +939,24 @@ start_p3dpython(P3DInstance *inst) {
|
||||
|
||||
// Get the log filename from the p3d_info.xml file.
|
||||
string log_basename = inst->_log_basename;
|
||||
bool has_log_basename = inst->_has_log_basename;
|
||||
|
||||
// But we also let it be overridden by the tokens.
|
||||
if (inst->get_fparams().has_token("log_basename")) {
|
||||
log_basename = inst->get_fparams().lookup_token("log_basename");
|
||||
has_log_basename = true;
|
||||
}
|
||||
|
||||
if (!has_log_basename) {
|
||||
#ifdef P3D_PLUGIN_LOG_BASENAME3
|
||||
if (log_basename.empty()) {
|
||||
// No log_basename specified for the app; use the compiled-in
|
||||
// default.
|
||||
log_basename = P3D_PLUGIN_LOG_BASENAME3;
|
||||
}
|
||||
#endif
|
||||
if (log_basename.empty()) {
|
||||
log_basename = "p3dsession";
|
||||
}
|
||||
}
|
||||
|
||||
// However, it is always written into the log directory only; the
|
||||
// user may not override the log file to put it anywhere else.
|
||||
@ -975,6 +988,7 @@ start_p3dpython(P3DInstance *inst) {
|
||||
// Create the pipe to the process.
|
||||
if (!CreatePipe(&r_to, &w_to, NULL, 0)) {
|
||||
nout << "failed to create pipe\n";
|
||||
set_failed();
|
||||
} else {
|
||||
// Make sure the right end of the pipe is inheritable.
|
||||
SetHandleInformation(r_to, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
||||
@ -984,6 +998,7 @@ start_p3dpython(P3DInstance *inst) {
|
||||
// Create the pipe from the process.
|
||||
if (!CreatePipe(&r_from, &w_from, NULL, 0)) {
|
||||
nout << "failed to create pipe\n";
|
||||
set_failed();
|
||||
} else {
|
||||
// Make sure the right end of the pipe is inheritable.
|
||||
SetHandleInformation(w_from, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
||||
@ -1000,10 +1015,12 @@ start_p3dpython(P3DInstance *inst) {
|
||||
int to_fd[2];
|
||||
if (pipe(to_fd) < 0) {
|
||||
perror("failed to create pipe");
|
||||
set_failed();
|
||||
}
|
||||
int from_fd[2];
|
||||
if (pipe(from_fd) < 0) {
|
||||
perror("failed to create pipe");
|
||||
set_failed();
|
||||
}
|
||||
|
||||
_input_handle = to_fd[0];
|
||||
@ -1012,6 +1029,10 @@ start_p3dpython(P3DInstance *inst) {
|
||||
_pipe_write.open_write(to_fd[1]);
|
||||
#endif // _WIN32
|
||||
|
||||
if (_failed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the filename of the Panda3D multifile. We need to pass this
|
||||
// to p3dpython.
|
||||
_mf_filename = inst->_panda3d->get_archive_file_pathname();
|
||||
@ -1074,6 +1095,30 @@ start_p3dpython(P3DInstance *inst) {
|
||||
_commands.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSession::set_failed
|
||||
// Access: Private
|
||||
// Description: Sets the "failed" indication to display sadness to
|
||||
// the user--we're unable to launch the instance for
|
||||
// some reason.
|
||||
//
|
||||
// When this is called on the P3DSession instead of on a
|
||||
// particular P3DInstance, it means that all instances
|
||||
// attached to this session are marked failed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSession::
|
||||
set_failed() {
|
||||
_failed = true;
|
||||
|
||||
Instances::iterator ii;
|
||||
ACQUIRE_LOCK(_instances_lock);
|
||||
for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
|
||||
P3DInstance *inst = (*ii).second;
|
||||
inst->set_failed();
|
||||
}
|
||||
RELEASE_LOCK(_instances_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSession::spawn_read_thread
|
||||
// Access: Private
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
|
||||
private:
|
||||
void start_p3dpython(P3DInstance *inst);
|
||||
void set_failed();
|
||||
|
||||
void spawn_read_thread();
|
||||
void join_read_thread();
|
||||
@ -93,6 +94,7 @@ private:
|
||||
string _python_root_dir;
|
||||
string _start_dir;
|
||||
bool _keep_user_env;
|
||||
bool _failed;
|
||||
|
||||
// This information is passed to create_process(), or to
|
||||
// p3dpython_thread_run().
|
||||
|
@ -152,7 +152,7 @@ run(int argc, char *argv[]) {
|
||||
|
||||
case 'l':
|
||||
_log_dirname = Filename::from_os_specific(optarg).to_os_specific();
|
||||
_log_basename = "panda3d";
|
||||
_log_basename = "p3dcore";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
|
Loading…
x
Reference in New Issue
Block a user