From ae3d2aceb467c6246ccb7f66f275a82fb421ba1e Mon Sep 17 00:00:00 2001 From: David Rose Date: Sun, 14 Jun 2009 15:51:32 +0000 Subject: [PATCH] still working on it --- direct/src/plugin/Sources.pp | 4 +- direct/src/plugin/p3dFileDownload.cxx | 3 +- direct/src/plugin/p3dInstanceManager.cxx | 5 ++ direct/src/plugin/p3dPackage.I | 11 ++++ direct/src/plugin/p3dPackage.cxx | 35 ++++++++-- direct/src/plugin/p3dPackage.h | 1 + direct/src/plugin/p3dSession.cxx | 83 +++++++++++++----------- direct/src/plugin/p3dSession.h | 25 ++++--- 8 files changed, 112 insertions(+), 55 deletions(-) diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 2f6962d992..5828fbf845 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -1,9 +1,9 @@ // This directory is still experimental. Define HAVE_P3D_PLUGIN in // your Config.pp to build it. -#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_PYTHON],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB]] +#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_PYTHON],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB],$[HAVE_TAR]] #begin lib_target - #define USE_PACKAGES tinyxml openssl zlib + #define USE_PACKAGES tinyxml openssl zlib tar #define TARGET p3d_plugin #define COMBINED_SOURCES \ diff --git a/direct/src/plugin/p3dFileDownload.cxx b/direct/src/plugin/p3dFileDownload.cxx index bcfcb5bd72..e370adfc2b 100755 --- a/direct/src/plugin/p3dFileDownload.cxx +++ b/direct/src/plugin/p3dFileDownload.cxx @@ -44,8 +44,7 @@ set_filename(const string &filename) { //////////////////////////////////////////////////////////////////// bool P3DFileDownload:: open_file() { - unlink(_filename.c_str()); - _file.open(_filename.c_str(), ios::out | ios::trunc | ios::binary); + _file.open(_filename.c_str(), ios::out | ios::ate | ios::binary); if (!_file) { return false; } diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 2a74b263c9..90c3843aae 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -73,8 +73,13 @@ P3DInstanceManager:: //////////////////////////////////////////////////////////////////// bool P3DInstanceManager:: initialize() { +#ifdef _WIN32 _root_dir = "c:/cygwin/home/drose/p3ddir"; _download_url = "http://10.196.143.118/~drose/"; +#else + _root_dir = "/Users/drose/p3ddir"; + _download_url = "http://orpheus.ddrose.com/~drose/"; +#endif return true; } diff --git a/direct/src/plugin/p3dPackage.I b/direct/src/plugin/p3dPackage.I index 821d5a5d1e..379b853251 100755 --- a/direct/src/plugin/p3dPackage.I +++ b/direct/src/plugin/p3dPackage.I @@ -36,6 +36,17 @@ get_failed() const { return _failed; } +//////////////////////////////////////////////////////////////////// +// Function: P3DPackage::get_package_dir +// Access: Public +// Description: Returns the directory into which this package is +// installed. +//////////////////////////////////////////////////////////////////// +inline const string &P3DPackage:: +get_package_dir() const { + return _package_dir; +} + //////////////////////////////////////////////////////////////////// // Function: P3DPackage::decode_hexdigit // Access: Private diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index 1e15c1b082..ed77638311 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -17,9 +17,11 @@ #include "openssl/md5.h" #include "zlib.h" +#include "libtar.h" #include #include +#include #include #include @@ -110,6 +112,7 @@ set_callback(Callback *callback) { if (_ready || _failed) { // Actually, we're already done. Signal the callback immediately. callback->package_ready(this, _ready); + delete callback; } else { // Bootstrap still in progress. Save the callback. _callbacks.push_back(callback); @@ -360,6 +363,28 @@ void P3DPackage:: extract_archive() { cerr << "extracting " << _uncompressed_archive._filename << "\n"; + string source_pathname = _package_dir + "/" + _uncompressed_archive._filename; + + TAR *tar = NULL; + int result = tar_open + (&tar, (char *)source_pathname.c_str(), NULL, O_RDONLY, 0666, TAR_VERBOSE); + if (result != 0) { + cerr << "Unable to open " << source_pathname << "\n"; + report_done(false); + return; + } + + while (th_read(tar) == 0) { + string basename = th_get_pathname(tar); + cerr << basename << "\n"; + string pathname = _package_dir + "/" + basename; + tar_extract_file(tar, (char *)pathname.c_str()); + } + + tar_close(tar); + + cerr << "done extracting\n"; + report_done(true); } //////////////////////////////////////////////////////////////////// @@ -371,6 +396,7 @@ extract_archive() { //////////////////////////////////////////////////////////////////// void P3DPackage:: report_done(bool success) { + cerr << "report_done(" << success << ")\n"; if (success) { _ready = true; _failed = false; @@ -384,6 +410,7 @@ report_done(bool success) { Callbacks::iterator ci; for (ci = orig_callbacks.begin(); ci != orig_callbacks.end(); ++ci) { (*ci)->package_ready(this, _ready); + delete (*ci); } // We shouldn't have added any more callbacks during the above loop. @@ -400,6 +427,10 @@ start_download(P3DPackage::DownloadType dtype, const string &url, const string &pathname, bool allow_partial) { // Only one download should be active at a time assert(_active_download == NULL); + + if (!allow_partial) { + unlink(pathname.c_str()); + } Download *download = new Download(this, dtype); download->set_url(url); @@ -407,10 +438,6 @@ start_download(P3DPackage::DownloadType dtype, const string &url, // TODO: implement partial file re-download. allow_partial = false; - - if (!allow_partial) { - unlink(pathname.c_str()); - } _active_download = download; _partial_download = false; diff --git a/direct/src/plugin/p3dPackage.h b/direct/src/plugin/p3dPackage.h index 32b0c4a5ae..9832d869d6 100755 --- a/direct/src/plugin/p3dPackage.h +++ b/direct/src/plugin/p3dPackage.h @@ -42,6 +42,7 @@ public: inline bool get_ready() const; inline bool get_failed() const; + inline const string &get_package_dir() const; void set_callback(Callback *callback); void cancel_callback(Callback *callback); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 2c3f755517..513e513da3 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -34,18 +34,18 @@ P3DSession(P3DInstance *inst) { _session_key = inst->get_session_key(); _python_version = inst->get_python_version(); -#ifdef _WIN32 - _python_root_dir = "C:/p3drun"; -#else - _python_root_dir = "/Users/drose/p3drun"; -#endif - - _python_state = PS_init; + _p3dpython_running = false; _started_read_thread = false; _read_thread_continue = false; _output_filename = inst->lookup_token("output_filename"); + P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); + + _panda3d = inst_mgr->get_package("panda3d", "dev"); + _panda3d_callback = NULL; + _python_root_dir = _panda3d->get_package_dir(); + INIT_LOCK(_instances_lock); } @@ -58,7 +58,12 @@ P3DSession(P3DInstance *inst) { //////////////////////////////////////////////////////////////////// P3DSession:: ~P3DSession() { - if (_python_state == PS_running) { + if (_panda3d_callback != NULL) { + _panda3d->cancel_callback(_panda3d_callback); + delete _panda3d_callback; + } + + if (_p3dpython_running) { // Tell the process we're going away. TiXmlDocument doc; TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); @@ -131,9 +136,16 @@ start_instance(P3DInstance *inst) { send_command(doc); - P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); - // P3DPackage *panda = inst_mgr->get_package("panda3d", "dev"); - start_p3dpython(); + if (_panda3d->get_ready()) { + // If it's ready immediately, go ahead and start. + start_p3dpython(); + } else { + // Otherwise, set a callback, so we'll know when it is ready. + if (_panda3d_callback != NULL) { + _panda3d_callback = new PackageCallback(this); + _panda3d->set_callback(_panda3d_callback); + } + } } //////////////////////////////////////////////////////////////////// @@ -177,7 +189,7 @@ terminate_instance(P3DInstance *inst) { //////////////////////////////////////////////////////////////////// void P3DSession:: send_command(TiXmlDocument *command) { - if (_python_state == PS_running) { + if (_p3dpython_running) { // Python is running. Send the command. _pipe_write << *command << flush; delete command; @@ -187,31 +199,6 @@ send_command(TiXmlDocument *command) { } } -//////////////////////////////////////////////////////////////////// -// Function: P3DSession::download_p3dpython -// Access: Private -// Description: Starts the Python package downloading. Once it is -// fully downloaded and unpacked, automatically calls -// start_p3dpython. -//////////////////////////////////////////////////////////////////// -void P3DSession:: -download_p3dpython(P3DInstance *inst) { - /* - P3DFileDownload *download = new P3DFileDownload(); - download->set_url("http://fewmet/~drose/p3drun.tgz"); - - string local_filename = "temp.tgz"; - if (!download->set_filename(local_filename)) { - cerr << "Could not open " << local_filename << "\n"; - return; - } - - inst->start_download(download); - */ - - // start_p3dpython(); -} - //////////////////////////////////////////////////////////////////// // Function: P3DSession::start_p3dpython // Access: Private @@ -281,7 +268,7 @@ start_p3dpython() { cerr << "Failed to create process.\n"; return; } - _python_state = PS_running; + _p3dpython_running = true; cerr << "Created child process\n"; @@ -640,3 +627,23 @@ posix_create_process(const string &program, const string &start_dir, return child; } #endif // _WIN32 + + +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::PackageCallback::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DSession::PackageCallback:: +PackageCallback(P3DSession *session) { +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::PackageCallback::package_ready +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void P3DSession::PackageCallback:: +package_ready(P3DPackage *package, bool success) { +} + diff --git a/direct/src/plugin/p3dSession.h b/direct/src/plugin/p3dSession.h index 0ec03651e0..032f5c7e3f 100644 --- a/direct/src/plugin/p3dSession.h +++ b/direct/src/plugin/p3dSession.h @@ -17,6 +17,7 @@ #include "p3d_plugin_common.h" #include "handleStream.h" +#include "p3dPackage.h" #include #include @@ -46,7 +47,6 @@ public: private: void send_command(TiXmlDocument *command); - void download_p3dpython(P3DInstance *inst); void start_p3dpython(); void spawn_read_thread(); @@ -76,14 +76,6 @@ private: #endif private: - enum PythonState { - PS_init, - PS_downloading, - PS_running, - PS_done, - }; - PythonState _python_state; - string _session_key; string _python_version; string _output_filename; @@ -100,12 +92,25 @@ private: typedef vector Commands; Commands _commands; + class PackageCallback : public P3DPackage::Callback { + public: + PackageCallback(P3DSession *session); + virtual void package_ready(P3DPackage *package, bool success); + + private: + P3DSession *_session; + }; + + P3DPackage *_panda3d; + PackageCallback *_panda3d_callback; + // Members for communicating with the p3dpython child process. #ifdef _WIN32 HANDLE _p3dpython_handle; #else int _p3dpython_pid; #endif + bool _p3dpython_running; // The remaining members are manipulated by or for the read thread. bool _started_read_thread; @@ -118,6 +123,8 @@ private: #else pthread_t _read_thread; #endif + + friend class PackageCallback; }; #include "p3dSession.I"