From 427a22573ad0ec3007df7a01653688e96bd82fa3 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 11 Jun 2009 20:56:16 +0000 Subject: [PATCH] log files, etc --- direct/src/plugin/p3dInstance.cxx | 35 +++++++++++++++++++----- direct/src/plugin/p3dInstance.h | 5 ++-- direct/src/plugin/p3dInstanceManager.cxx | 4 +-- direct/src/plugin/p3dInstanceManager.h | 2 +- direct/src/plugin/p3dSession.cxx | 27 +++++++++++++++++- direct/src/plugin/p3d_plugin.cxx | 5 ++-- direct/src/plugin/p3d_plugin.h | 20 +++++++++++--- direct/src/plugin/panda3d.cxx | 33 ++++++++++++++++++++-- direct/src/showbase/ShowBase.py | 2 +- 9 files changed, 110 insertions(+), 23 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 59b7ae948b..30d1caa03a 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -31,7 +31,7 @@ P3DInstance(P3D_request_ready_func *func, int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size) : + const P3D_token tokens[], size_t num_tokens) : _func(func), _p3d_filename(p3d_filename), _window_type(window_type), @@ -39,6 +39,8 @@ P3DInstance(P3D_request_ready_func *func, _win_width(win_width), _win_height(win_height), _parent_window(parent_window) { + fill_tokens(tokens, num_tokens); + _instance_id = _next_instance_id; ++_next_instance_id; @@ -196,6 +198,25 @@ feed_url_stream(int unique_id, size_t this_data_size) { } +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::lookup_token +// Access: Public +// Description: Returns the value associated with the first +// appearance of the named token, or empty string if the +// token does not appear. +//////////////////////////////////////////////////////////////////// +string P3DInstance:: +lookup_token(const string &keyword) const { + Tokens::const_iterator ti; + for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { + if ((*ti)._keyword == keyword) { + return (*ti)._value; + } + } + + return string(); +} + //////////////////////////////////////////////////////////////////// // Function: P3DInstance::make_xml // Access: Public @@ -249,14 +270,14 @@ make_xml() { // C++-style _tokens vector. //////////////////////////////////////////////////////////////////// void P3DInstance:: -fill_tokens(const P3D_token *tokens[], size_t tokens_size) { - for (size_t i = 0; i < tokens_size; ++i) { +fill_tokens(const P3D_token tokens[], size_t num_tokens) { + for (size_t i = 0; i < num_tokens; ++i) { Token token; - if (tokens[i]->_keyword != NULL) { - token._keyword = tokens[i]->_keyword; + if (tokens[i]._keyword != NULL) { + token._keyword = tokens[i]._keyword; } - if (tokens[i]->_value != NULL) { - token._value = tokens[i]->_value; + if (tokens[i]._value != NULL) { + token._value = tokens[i]._value; } _tokens.push_back(token); } diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 95f4f46b15..9a7ea3f20a 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -36,7 +36,7 @@ public: int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size); + const P3D_token tokens[], size_t num_tokens); ~P3DInstance(); bool has_property(const string &property_name) const; @@ -59,11 +59,12 @@ public: inline int get_instance_id() const; inline const string &get_session_key() const; inline const string &get_python_version() const; + string lookup_token(const string &keyword) const; TiXmlElement *make_xml(); private: - void fill_tokens(const P3D_token *tokens[], size_t tokens_size); + void fill_tokens(const P3D_token tokens[], size_t num_tokens); class Token { public: diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 06fb68a408..5ea4e5770c 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -79,11 +79,11 @@ create_instance(P3D_request_ready_func *func, int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size) { + const P3D_token tokens[], size_t num_tokens) { P3DInstance *inst = new P3DInstance(func, p3d_filename, window_type, win_x, win_y, win_width, win_height, parent_window, - tokens, tokens_size); + tokens, num_tokens); _instances.insert(inst); P3DSession *session; diff --git a/direct/src/plugin/p3dInstanceManager.h b/direct/src/plugin/p3dInstanceManager.h index 9c0d93b004..6c73c63a8a 100644 --- a/direct/src/plugin/p3dInstanceManager.h +++ b/direct/src/plugin/p3dInstanceManager.h @@ -43,7 +43,7 @@ public: int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size); + const P3D_token tokens[], size_t num_tokens); void finish_instance(P3DInstance *inst); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index e222751124..3dc5d5e833 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -92,6 +92,24 @@ P3DSession(P3DInstance *inst) { SetHandleInformation(r_from, HANDLE_FLAG_INHERIT, 0); } + HANDLE error_handle = GetStdHandle(STD_ERROR_HANDLE); + string output_filename = inst->lookup_token("output_filename"); + bool got_output_filename = !output_filename.empty(); + if (got_output_filename) { + // Open the named file for output and redirect the child's stderr + // into it. + HANDLE handle = CreateFile + (output_filename.c_str(), GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, CREATE_ALWAYS, 0, NULL); + if (handle != INVALID_HANDLE_VALUE) { + error_handle = handle; + SetHandleInformation(error_hanlesdle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + } else { + cerr << "Unable to open " << output_filename << "\n"; + } + } + // Make sure we see an error dialog if there is a missing DLL. SetErrorMode(0); @@ -100,10 +118,14 @@ P3DSession(P3DInstance *inst) { STARTUPINFO startup_info; ZeroMemory(&startup_info, sizeof(STARTUPINFO)); startup_info.cb = sizeof(startup_info); - startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + startup_info.hStdError = error_handle; startup_info.hStdOutput = w_from; startup_info.hStdInput = r_to; startup_info.dwFlags |= STARTF_USESTDHANDLES; + + // Make sure the "python" console window is hidden. + startup_info.wShowWindow = SW_HIDE; + startup_info.dwFlags |= STARTF_USESHOWWINDOW; BOOL result = CreateProcess (p3dpython.c_str(), NULL, NULL, NULL, TRUE, 0, @@ -120,6 +142,9 @@ P3DSession(P3DInstance *inst) { // Close the pipe handles that are now owned by the child. CloseHandle(w_from); CloseHandle(r_to); + if (got_output_filename) { + CloseHandle(error_handle); + } _pipe_read.open_read(r_from); _pipe_write.open_write(w_to); diff --git a/direct/src/plugin/p3d_plugin.cxx b/direct/src/plugin/p3d_plugin.cxx index cdb1b08ebd..8e60e5b24e 100644 --- a/direct/src/plugin/p3d_plugin.cxx +++ b/direct/src/plugin/p3d_plugin.cxx @@ -29,6 +29,7 @@ P3D_initialize() { initialized_lock = true; } ACQUIRE_LOCK(_lock); + P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); bool result = inst_mgr->initialize(); RELEASE_LOCK(_lock); @@ -49,13 +50,13 @@ P3D_create_instance(P3D_request_ready_func *func, int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size) { + const P3D_token tokens[], size_t num_tokens) { ACQUIRE_LOCK(_lock); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); P3DInstance *result = inst_mgr->create_instance(func, p3d_filename, window_type, win_x, win_y, win_width, win_height, - parent_window, tokens, tokens_size); + parent_window, tokens, num_tokens); RELEASE_LOCK(_lock); return result; } diff --git a/direct/src/plugin/p3d_plugin.h b/direct/src/plugin/p3d_plugin.h index a88c964c36..77b72b5f20 100644 --- a/direct/src/plugin/p3d_plugin.h +++ b/direct/src/plugin/p3d_plugin.h @@ -174,8 +174,8 @@ P3D_request_ready_func(P3D_instance *instance); additional keywords that may appear within this syntax; it is up to the plugin to interpret these additional keywords correctly. */ typedef struct { - char *_keyword; - char *_value; + const char *_keyword; + const char *_value; } P3D_token; /* This function creates a new Panda3D instance. For p3d_filename @@ -185,7 +185,19 @@ typedef struct { the user-supplied keyword/value pairs that may appear in the embed token within the HTML syntax; the host is responsible for allocating this array, and for deallocating it after this call (the - plugin will make its own copy of the array). */ + plugin will make its own copy of the array). + + Most tokens are implemented by the application and are undefined at + the system level. However, one token in particular is + system-defined: + + "output_filename" : names a file to create on disk which contains + the console output from the application. This may be useful in + debugging. If this is omitted, or an empty string, the console + output is written to the standard error output, which may be + NULL on a gui application. + + */ typedef P3D_instance * P3D_create_instance_func(P3D_request_ready_func *func, @@ -194,7 +206,7 @@ P3D_create_instance_func(P3D_request_ready_func *func, int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const P3D_token *tokens[], size_t tokens_size); + const P3D_token tokens[], size_t num_tokens); /* Call this function to interrupt a particular instance and stop it diff --git a/direct/src/plugin/panda3d.cxx b/direct/src/plugin/panda3d.cxx index c2411bf184..31cf95667b 100644 --- a/direct/src/plugin/panda3d.cxx +++ b/direct/src/plugin/panda3d.cxx @@ -326,6 +326,11 @@ usage() { << " run. Normally, this will be found by searching in the usual\n" << " places.\n\n" + << " -l output.log\n" + << " Specify the name of the file to receive the log output of the\n" + << " plugin process(es). The default is to send this output to the\n" + << " console.\n\n" + << " -t [toplevel|embedded|fullscreen|hidden]\n" << " Specify the type of graphic window to create. If you specify " << " \"embedded\", a new window is created to be the parent.\n\n" @@ -355,11 +360,24 @@ parse_int_pair(char *arg, int &x, int &y) { int main(int argc, char *argv[]) { +/* +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + char *targv[] = { + "panda3d", + "-tembedded", + "c:/cygwin/home/drose/ralph.p3d", + NULL, + }; + char **argv = targv; + int argc = 3; +*/ + extern char *optarg; extern int optind; - const char *optstr = "p:t:s:o:h"; + const char *optstr = "p:l:t:s:o:h"; string p3d_plugin_filename; + string output_filename; P3D_window_type window_type = P3D_WT_toplevel; int win_x = 0, win_y = 0; int win_width = 0, win_height = 0; @@ -372,6 +390,10 @@ main(int argc, char *argv[]) { p3d_plugin_filename = optarg; break; + case 'l': + output_filename = optarg; + break; + case 't': if (strcmp(optarg, "toplevel") == 0) { window_type = P3D_WT_toplevel; @@ -425,6 +447,11 @@ main(int argc, char *argv[]) { int num_instances = argc - 1; + P3D_token tokens[] = { + { "output_filename", output_filename.c_str() }, + }; + int num_tokens = sizeof(tokens) / sizeof(P3D_token); + P3D_window_handle parent_window; if (window_type == P3D_WT_embedded) { // The user asked for an embedded window. Create a toplevel @@ -468,7 +495,7 @@ main(int argc, char *argv[]) { P3D_instance *inst = P3D_create_instance (NULL, argv[i + 1], P3D_WT_embedded, inst_x, inst_y, inst_width, inst_height, parent_window, - NULL, 0); + tokens, num_tokens); _instances.insert(inst); } } @@ -479,7 +506,7 @@ main(int argc, char *argv[]) { P3D_instance *inst = P3D_create_instance (NULL, argv[i + 1], window_type, win_x, win_y, win_width, win_height, parent_window, - NULL, 0); + tokens, num_tokens); _instances.insert(inst); } } diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 76c3d2dd18..f03e79faae 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -837,7 +837,7 @@ class ShowBase(DirectObject.DirectObject): self.taskMgr.add(self.sleepCycleTask, 'clientSleep', priority = 55) def sleepCycleTask(self, task): - time.sleep(self.clientSleep) + Thread.sleep(self.clientSleep) return Task.cont def setFrameRateMeter(self, flag):