From 891051485da777589ab3c51d83c2a8ad7bf42450 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 3 Jul 2009 01:24:50 +0000 Subject: [PATCH] command-and-response --- direct/src/plugin/Sources.pp | 2 + direct/src/plugin/p3dConditionVar.I | 14 ++ direct/src/plugin/p3dConditionVar.cxx | 136 ++++++++++++++++++++ direct/src/plugin/p3dConditionVar.h | 49 +++++++ direct/src/plugin/p3dInstance.cxx | 32 ----- direct/src/plugin/p3dInstance.h | 1 - direct/src/plugin/p3dInstanceManager.cxx | 46 ++----- direct/src/plugin/p3dInstanceManager.h | 10 +- direct/src/plugin/p3dPythonRun.cxx | 73 ++++++++--- direct/src/plugin/p3dPythonRun.h | 2 + direct/src/plugin/p3dSession.cxx | 119 ++++++++++++++++- direct/src/plugin/p3dSession.h | 9 ++ direct/src/plugin/p3d_plugin_composite1.cxx | 20 +-- 13 files changed, 404 insertions(+), 109 deletions(-) create mode 100644 direct/src/plugin/p3dConditionVar.I create mode 100644 direct/src/plugin/p3dConditionVar.cxx create mode 100644 direct/src/plugin/p3dConditionVar.h diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 1c92dba9a8..aec2419412 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -21,6 +21,7 @@ p3d_plugin_config.h \ p3d_plugin_common.h \ p3dBoolObject.h \ + p3dConditionVar.h p3dConditionVar.I \ p3dDownload.h p3dDownload.I \ p3dFileDownload.h p3dFileDownload.I \ p3dFileParams.h p3dFileParams.I \ @@ -41,6 +42,7 @@ #define INCLUDED_SOURCES \ p3d_plugin.cxx \ p3dBoolObject.cxx \ + p3dConditionVar.cxx \ p3dDownload.cxx \ p3dFileDownload.cxx \ p3dFileParams.cxx \ diff --git a/direct/src/plugin/p3dConditionVar.I b/direct/src/plugin/p3dConditionVar.I new file mode 100644 index 0000000000..d987a00c57 --- /dev/null +++ b/direct/src/plugin/p3dConditionVar.I @@ -0,0 +1,14 @@ +// Filename: p3dConditionVar.I +// Created by: drose (02Jul09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + diff --git a/direct/src/plugin/p3dConditionVar.cxx b/direct/src/plugin/p3dConditionVar.cxx new file mode 100644 index 0000000000..5984cbf8f5 --- /dev/null +++ b/direct/src/plugin/p3dConditionVar.cxx @@ -0,0 +1,136 @@ +// Filename: p3dConditionVar.cxx +// Created by: drose (02Jul09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "p3dConditionVar.h" + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DConditionVar:: +P3DConditionVar() { +#ifdef _WIN32 + InitializeCriticalSection(&_lock); + + // Create an auto-reset event. + _event_signal = CreateEvent(NULL, false, false, NULL); + +#else // _WIN32 + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + int result = pthread_mutex_init(&_lock, &attr); + pthread_mutexattr_destroy(&attr); + assert(result == 0); + + result = pthread_cond_init(&_cvar, NULL); + assert(result == 0); + +#endif // _WIN32 +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DConditionVar:: +~P3DConditionVar() { +#ifdef _WIN32 + DeleteCriticalSection(&_lock); + CloseHandle(_event_signal); + +#else // _WIN32 + int result = pthread_mutex_destroy(&_lock); + assert(result == 0); + + result = pthread_cond_destroy(&_cvar); + assert(result == 0); + +#endif // _WIN32 +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::acquire +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void P3DConditionVar:: +acquire() { +#ifdef _WIN32 + EnterCriticalSection(&_lock); + +#else // _WIN32 + int result = pthread_mutex_lock(&_lock); + assert(result == 0); + +#endif // _WIN32 +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::wait +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void P3DConditionVar:: +wait() { +#ifdef _WIN32 + LeaveCriticalSection(&_lock); + + DWORD result = WaitForSingleObject(_event_signal, INFINITE); + assert(result == WAIT_OBJECT_0); + + EnterCriticalSection(&_lock); + +#else // _WIN32 + int result = pthread_cond_wait(&_cvar, &_mutex._lock); + assert(result == 0); + +#endif // _WIN32 +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::notify +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void P3DConditionVar:: +notify() { +#ifdef _WIN32 + SetEvent(_event_signal); + +#else // _WIN32 + int result = pthread_cond_signal(&_cvar); + assert(result == 0); + +#endif // _WIN32 +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DConditionVar::release +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void P3DConditionVar:: +release() { +#ifdef _WIN32 + LeaveCriticalSection(&_lock); + +#else // _WIN32 + int result = pthread_mutex_unlock(&_lock); + assert(result == 0); + +#endif // _WIN32 +} diff --git a/direct/src/plugin/p3dConditionVar.h b/direct/src/plugin/p3dConditionVar.h new file mode 100644 index 0000000000..63fd77f48e --- /dev/null +++ b/direct/src/plugin/p3dConditionVar.h @@ -0,0 +1,49 @@ +// Filename: p3dConditionVar.h +// Created by: drose (02Jul09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef P3DCONDITIONVAR_H +#define P3DCONDITIONVAR_H + +#include "p3d_plugin_common.h" + +//////////////////////////////////////////////////////////////////// +// Class : P3DConditionVar +// Description : A simple condition-variable like object. It doesn't +// support the full condition-var semantics, but it +// works well enough with one waiter and one signaller. +//////////////////////////////////////////////////////////////////// +class P3DConditionVar { +public: + P3DConditionVar(); + ~P3DConditionVar(); + + void acquire(); + void wait(); + void notify(); + void release(); + +private: +#ifdef _WIN32 + CRITICAL_SECTION _lock; + HANDLE _event_signal; + +#else // _WIN32 + pthread_mutex_t _lock; + pthread_cond_t _cvar; +#endif // _WIN32 +}; + +#include "p3dConditionVar.I" + +#endif diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 29e35c1487..65e7d34352 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -345,38 +345,6 @@ feed_url_stream(int unique_id, return download_ok; } -//////////////////////////////////////////////////////////////////// -// Function: P3DInstance::feed_value -// Access: Public -// Description: Called by the host in response to a get_property or -// call request. The value object must have been -// freshly allocated; it will be deleted by this method. -//////////////////////////////////////////////////////////////////// -void P3DInstance:: -feed_value(int unique_id, P3DObject *value) { - if (_session != NULL) { - TiXmlDocument *doc = new TiXmlDocument; - TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", ""); - TiXmlElement *xcommand = new TiXmlElement("command"); - xcommand->SetAttribute("cmd", "feed_value"); - xcommand->SetAttribute("instance_id", get_instance_id()); - xcommand->SetAttribute("unique_id", unique_id); - if (value != NULL) { - TiXmlElement *xvalue = value->make_xml(); - xcommand->LinkEndChild(xvalue); - } - - doc->LinkEndChild(decl); - doc->LinkEndChild(xcommand); - - _session->send_command(doc); - } - - if (value != NULL) { - delete value; - } -} - //////////////////////////////////////////////////////////////////// // Function: P3DInstance::add_package // Access: Public diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 85c67bec9b..fdf5e1bf14 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -63,7 +63,6 @@ public: size_t total_expected_data, const unsigned char *this_data, size_t this_data_size); - void feed_value(int unique_id, P3DObject *value); inline int get_instance_id() const; inline const string &get_session_key() const; diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 5525e905b9..e47f49b1af 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -38,14 +38,6 @@ P3DInstanceManager() { _is_initialized = false; _unique_session_index = 0; - _request_seq = 0; -#ifdef _WIN32 - _request_ready = CreateEvent(NULL, false, false, NULL); -#else - INIT_LOCK(_request_ready_lock); - pthread_cond_init(&_request_ready_cvar, NULL); -#endif - #ifdef _WIN32 // Ensure the appropriate Windows common controls are available to // this application. @@ -68,13 +60,6 @@ P3DInstanceManager:: assert(_instances.empty()); assert(_sessions.empty()); - -#ifdef _WIN32 - CloseHandle(_request_ready); -#else - DESTROY_LOCK(_request_ready_lock); - pthread_cond_destroy(&_request_ready_cvar); -#endif } //////////////////////////////////////////////////////////////////// @@ -211,30 +196,21 @@ check_request() { //////////////////////////////////////////////////////////////////// void P3DInstanceManager:: wait_request() { - int seq = _request_seq; - + _request_ready.acquire(); while (true) { if (check_request() != (P3DInstance *)NULL) { + _request_ready.release(); return; } if (_instances.empty()) { + _request_ready.release(); return; } // No pending requests; go to sleep. -#ifdef _WIN32 - if (seq == _request_seq) { - WaitForSingleObject(_request_ready, INFINITE); - } -#else - ACQUIRE_LOCK(_request_ready_lock); - if (seq == _request_seq) { - pthread_cond_wait(&_request_ready_cvar, &_request_ready_lock); - } - RELEASE_LOCK(_request_ready_lock); -#endif - seq = _request_seq; + _request_ready.wait(); } + _request_ready.release(); } //////////////////////////////////////////////////////////////////// @@ -283,15 +259,9 @@ get_unique_session_index() { //////////////////////////////////////////////////////////////////// void P3DInstanceManager:: signal_request_ready() { -#ifdef _WIN32 - ++_request_seq; - SetEvent(_request_ready); -#else - ACQUIRE_LOCK(_request_ready_lock); - ++_request_seq; - pthread_cond_signal(&_request_ready_cvar); - RELEASE_LOCK(_request_ready_lock); -#endif + _request_ready.acquire(); + _request_ready.notify(); + _request_ready.release(); } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dInstanceManager.h b/direct/src/plugin/p3dInstanceManager.h index 6813685883..51da747a9d 100644 --- a/direct/src/plugin/p3dInstanceManager.h +++ b/direct/src/plugin/p3dInstanceManager.h @@ -16,6 +16,7 @@ #define P3DINSTANCEMANAGER_H #include "p3d_plugin_common.h" +#include "p3dConditionVar.h" #include #include @@ -83,14 +84,7 @@ private: int _unique_session_index; - // Implements a condition-var like behavior. - volatile int _request_seq; -#ifdef _WIN32 - HANDLE _request_ready; -#else - LOCK _request_ready_lock; - pthread_cond_t _request_ready_cvar; -#endif + P3DConditionVar _request_ready; static P3DInstanceManager *_global_ptr; }; diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 4a18c12bc7..f6de86904e 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -192,9 +192,17 @@ handle_command(TiXmlDocument *doc) { nout << "got command: " << *doc << "\n"; TiXmlElement *xcommand = doc->FirstChildElement("command"); if (xcommand != NULL) { + bool needs_response = false; + int want_response_id; + if (xcommand->QueryIntAttribute("want_response_id", &want_response_id) == TIXML_SUCCESS) { + // This command will be waiting for a response. + needs_response = true; + } + const char *cmd = xcommand->Attribute("cmd"); if (cmd != NULL) { if (strcmp(cmd, "start_instance") == 0) { + assert(!needs_response); TiXmlElement *xinstance = xcommand->FirstChildElement("instance"); if (xinstance != (TiXmlElement *)NULL) { P3DCInstance *inst = new P3DCInstance(xinstance); @@ -202,12 +210,14 @@ handle_command(TiXmlDocument *doc) { } } else if (strcmp(cmd, "terminate_instance") == 0) { + assert(!needs_response); int instance_id; if (xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS) { terminate_instance(instance_id); } } else if (strcmp(cmd, "setup_window") == 0) { + assert(!needs_response); int instance_id; TiXmlElement *xwparams = xcommand->FirstChildElement("wparams"); if (xwparams != (TiXmlElement *)NULL && @@ -216,34 +226,61 @@ handle_command(TiXmlDocument *doc) { } } else if (strcmp(cmd, "exit") == 0) { + assert(!needs_response); terminate_session(); - } else if (strcmp(cmd, "feed_value") == 0) { - int instance_id, unique_id; - if (xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS && - xcommand->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) { - // TODO: deal with instance_id. - TiXmlElement *xvalue = xcommand->FirstChildElement("value"); - if (xvalue != NULL) { - PyObject *value = from_xml_value(xvalue); - PyObject *result = PyObject_CallMethod - (_runner, (char*)"feedValue", (char*)"iOi", unique_id, value, true); - Py_DECREF(value); - Py_XDECREF(result); - } else { - PyObject *result = PyObject_CallMethod - (_runner, (char*)"feedValue", (char*)"iOi", unique_id, Py_None, false); - Py_XDECREF(result); - } - } + } else if (strcmp(cmd, "pyobj") == 0) { + // Manipulate or query a python object. Presumably this + // command will want a response. + assert(needs_response); + + handle_pyobj_command(xcommand, want_response_id); } else { nout << "Unhandled command " << cmd << "\n"; + if (needs_response) { + // Better send a response. + TiXmlDocument doc; + TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", ""); + TiXmlElement *xresponse = new TiXmlElement("response"); + xresponse->SetAttribute("response_id", want_response_id); + doc.LinkEndChild(decl); + doc.LinkEndChild(xresponse); + nout << "sending " << doc << "\n" << flush; + _pipe_write << doc << flush; + } } } } } +//////////////////////////////////////////////////////////////////// +// Function: P3DPythonRun::handle_pyobj_command +// Access: Private +// Description: Handles the pyobj command, which queries or modifies +// a Python object from the browser scripts. +//////////////////////////////////////////////////////////////////// +void P3DPythonRun:: +handle_pyobj_command(TiXmlElement *xcommand, int want_response_id) { + TiXmlDocument doc; + TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", ""); + TiXmlElement *xresponse = new TiXmlElement("response"); + xresponse->SetAttribute("response_id", want_response_id); + doc.LinkEndChild(decl); + doc.LinkEndChild(xresponse); + + const char *op = xcommand->Attribute("op"); + if (op != NULL) { + if (strcmp(op, "get_script_object") == 0) { + // Get the toplevel Python object. + xresponse->SetAttribute("object", "fooby"); + } + } + + nout << "sending " << doc << "\n" << flush; + _pipe_write << doc << flush; +} + //////////////////////////////////////////////////////////////////// // Function: P3DPythonRun::check_comm // Access: Private diff --git a/direct/src/plugin/p3dPythonRun.h b/direct/src/plugin/p3dPythonRun.h index 415e348699..a47d48d90c 100755 --- a/direct/src/plugin/p3dPythonRun.h +++ b/direct/src/plugin/p3dPythonRun.h @@ -70,6 +70,8 @@ public: private: void handle_command(TiXmlDocument *doc); + void handle_pyobj_command(TiXmlElement *xcommand, int want_response_id); + AsyncTask::DoneStatus check_comm(GenericAsyncTask *task); static AsyncTask::DoneStatus st_check_comm(GenericAsyncTask *task, void *user_data); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 414839289f..a0763947e0 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -36,6 +36,10 @@ P3DSession(P3DInstance *inst) { _python_version = inst->get_python_version(); _p3dpython_running = false; + _next_response_id = 0; + _response = NULL; + _got_response_id = -1; + _started_read_thread = false; _read_thread_continue = false; @@ -210,6 +214,78 @@ send_command(TiXmlDocument *command) { } } +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::command_and_response +// Access: Public +// Description: Sends the indicated command to the running Python +// process, and waits for a response. Returns the +// newly-allocated response on success, or NULL on +// failure. +// +// The command must be a newly-allocated TiXmlDocument; +// it will be deleted after it has been delivered to the +// process. +// +// This will fail if the python process is not running +// or if it suddenly stops. +//////////////////////////////////////////////////////////////////// +TiXmlDocument *P3DSession:: +command_and_response(TiXmlDocument *command) { + if (!_p3dpython_running) { + return NULL; + } + + int response_id = _next_response_id; + ++_next_response_id; + + // Add the "want_response_id" attribute to the toplevel command, so + // the sub-process knows we'll be waiting for its response. + TiXmlElement *xcommand = command->FirstChildElement("command"); + assert(xcommand != NULL); + xcommand->SetAttribute("want_response_id", response_id); + + _pipe_write << *command << flush; + delete command; + + // Now block, waiting for a response to be delivered. We assume + // only one thread will be waiting at a time. + nout << "Waiting for response " << response_id << "\n" << flush; + _response_ready.acquire(); + while (_response == NULL || _got_response_id != response_id) { + if (_response != NULL) { + // This is a bogus response. Since we're the only thread waiting, + // it follows that no one is waiting for this response, so we can + // throw it away. + nout << "Discarding bogus response: " << *_response << "\n"; + delete _response; + _response = NULL; + _got_response_id = -1; + } + + if (!_p3dpython_running) { + // Hmm, looks like Python has gone away. + + // TODO: make sure _p3dpython_running gets set to false when the + // process dies unexpectedly. + _response_ready.release(); + return NULL; + } + + _response_ready.wait(); + } + // When we exit the loop, we've found the desired response. + + TiXmlDocument *response = _response; + _response = NULL; + _got_response_id = -1; + + _response_ready.release(); + + nout << "Got response: " << *response << "\n" << flush; + + return response; +} + //////////////////////////////////////////////////////////////////// // Function: P3DSession::install_progress // Access: Private @@ -316,6 +392,22 @@ start_p3dpython() { } _pipe_write << flush; _commands.clear(); + + // Temp testing code. + { + TiXmlDocument *doc = new TiXmlDocument; + TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", ""); + TiXmlElement *xcommand = new TiXmlElement("command"); + xcommand->SetAttribute("cmd", "pyobj"); + xcommand->SetAttribute("op", "get"); + doc->LinkEndChild(decl); + doc->LinkEndChild(xcommand); + TiXmlDocument *response = command_and_response(doc); + nout << "response pointer: " << response << "\n"; + if (response != NULL) { + delete response; + } + } } //////////////////////////////////////////////////////////////////// @@ -409,10 +501,33 @@ void P3DSession:: rt_handle_request(TiXmlDocument *doc) { nout << "Session got request: " << *doc << "\n" << flush; + TiXmlElement *xresponse = doc->FirstChildElement("response"); + if (xresponse != (TiXmlElement *)NULL) { + int response_id; + if (xresponse->QueryIntAttribute("response_id", &response_id) == TIXML_SUCCESS) { + // This is a response to a previous command-and-response. Send + // it to the parent thread. + _response_ready.acquire(); + if (_response != NULL) { + // Hey, there's already a response there. Since there's only + // one thread waiting at a time on the command-response cycle, + // this must be a bogus response that never got picked up. + // Discard it. + nout << "Discarding bogus response: " << *_response << "\n"; + delete _response; + } + _response = doc; + _got_response_id = response_id; + _response_ready.notify(); + _response_ready.release(); + return; + } + } + TiXmlElement *xrequest = doc->FirstChildElement("request"); if (xrequest != (TiXmlElement *)NULL) { - int instance_id ; - if (xrequest->Attribute("instance_id", &instance_id)) { + int instance_id; + if (xrequest->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS) { // Look up the particular instance this is related to. ACQUIRE_LOCK(_instances_lock); Instances::const_iterator ii; diff --git a/direct/src/plugin/p3dSession.h b/direct/src/plugin/p3dSession.h index aeea1202fa..86270cd5f8 100644 --- a/direct/src/plugin/p3dSession.h +++ b/direct/src/plugin/p3dSession.h @@ -18,6 +18,7 @@ #include "p3d_plugin_common.h" #include "handleStream.h" #include "p3dPackage.h" +#include "p3dConditionVar.h" #include "get_tinyxml.h" #include @@ -47,6 +48,7 @@ public: inline int get_num_instances() const; void send_command(TiXmlDocument *command); + TiXmlDocument *command_and_response(TiXmlDocument *command); private: void install_progress(P3DPackage *package, double progress); @@ -120,6 +122,13 @@ private: #endif bool _p3dpython_running; + int _next_response_id; + + // The _response_ready mutex protects this pointer. + TiXmlDocument *_response; + int _got_response_id; + P3DConditionVar _response_ready; + // The remaining members are manipulated by or for the read thread. bool _started_read_thread; HandleStream _pipe_read; diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index 47abe17c3a..f17e2f16e9 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -1,20 +1,20 @@ #include "p3d_plugin.cxx" +#include "p3dBoolObject.cxx" +#include "p3dConditionVar.cxx" #include "p3dDownload.cxx" #include "p3dFileDownload.cxx" #include "p3dFileParams.cxx" +#include "p3dFloatObject.cxx" #include "p3dInstance.cxx" #include "p3dInstanceManager.cxx" +#include "p3dIntObject.cxx" +#include "p3dListObject.cxx" #include "p3dMultifileReader.cxx" #include "p3dNoneObject.cxx" -#include "p3dPackage.cxx" -#include "p3dSplashWindow.cxx" -#include "p3dSession.cxx" -#include "p3dWindowParams.cxx" -#include "p3dWinSplashWindow.cxx" #include "p3dObject.cxx" -#include "p3dBoolObject.cxx" -#include "p3dIntObject.cxx" -#include "p3dFloatObject.cxx" -#include "p3dListObject.cxx" +#include "p3dPackage.cxx" +#include "p3dSession.cxx" +#include "p3dSplashWindow.cxx" #include "p3dStringObject.cxx" - +#include "p3dWinSplashWindow.cxx" +#include "p3dWindowParams.cxx"