Browse Source

hey its working

David Rose 16 years ago
parent
commit
36eb5bc08a

+ 10 - 5
direct/src/plugin/load_plugin.cxx

@@ -33,7 +33,8 @@ static const string default_plugin_filename = "p3d_plugin";
 
 
 P3D_initialize_func *P3D_initialize;
 P3D_initialize_func *P3D_initialize;
 P3D_free_string_func *P3D_free_string;
 P3D_free_string_func *P3D_free_string;
-P3D_create_instance_func *P3D_create_instance;
+P3D_new_instance_func *P3D_new_instance;
+P3D_instance_start_func *P3D_instance_start;
 P3D_instance_finish_func *P3D_instance_finish;
 P3D_instance_finish_func *P3D_instance_finish;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 P3D_instance_has_property_func *P3D_instance_has_property;
 P3D_instance_has_property_func *P3D_instance_has_property;
@@ -147,7 +148,8 @@ load_plugin(const string &p3d_plugin_filename) {
   // Now get all of the function pointers.
   // Now get all of the function pointers.
   P3D_initialize = (P3D_initialize_func *)GetProcAddress(module, "P3D_initialize");  
   P3D_initialize = (P3D_initialize_func *)GetProcAddress(module, "P3D_initialize");  
   P3D_free_string = (P3D_free_string_func *)GetProcAddress(module, "P3D_free_string");  
   P3D_free_string = (P3D_free_string_func *)GetProcAddress(module, "P3D_free_string");  
-  P3D_create_instance = (P3D_create_instance_func *)GetProcAddress(module, "P3D_create_instance");  
+  P3D_new_instance = (P3D_new_instance_func *)GetProcAddress(module, "P3D_new_instance");  
+  P3D_instance_start = (P3D_instance_start_func *)GetProcAddress(module, "P3D_instance_start");  
   P3D_instance_finish = (P3D_instance_finish_func *)GetProcAddress(module, "P3D_instance_finish");  
   P3D_instance_finish = (P3D_instance_finish_func *)GetProcAddress(module, "P3D_instance_finish");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)GetProcAddress(module, "P3D_instance_setup_window");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)GetProcAddress(module, "P3D_instance_setup_window");  
   P3D_instance_has_property = (P3D_instance_has_property_func *)GetProcAddress(module, "P3D_instance_has_property");  
   P3D_instance_has_property = (P3D_instance_has_property_func *)GetProcAddress(module, "P3D_instance_has_property");  
@@ -170,7 +172,8 @@ load_plugin(const string &p3d_plugin_filename) {
   // Now get all of the function pointers.
   // Now get all of the function pointers.
   P3D_initialize = (P3D_initialize_func *)dlsym(module, "P3D_initialize");  
   P3D_initialize = (P3D_initialize_func *)dlsym(module, "P3D_initialize");  
   P3D_free_string = (P3D_free_string_func *)dlsym(module, "P3D_free_string");  
   P3D_free_string = (P3D_free_string_func *)dlsym(module, "P3D_free_string");  
-  P3D_create_instance = (P3D_create_instance_func *)dlsym(module, "P3D_create_instance");  
+  P3D_new_instance = (P3D_new_instance_func *)dlsym(module, "P3D_new_instance");  
+  P3D_instance_start = (P3D_instance_start_func *)dlsym(module, "P3D_instance_start");  
   P3D_instance_finish = (P3D_instance_finish_func *)dlsym(module, "P3D_instance_finish");  
   P3D_instance_finish = (P3D_instance_finish_func *)dlsym(module, "P3D_instance_finish");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)dlsym(module, "P3D_instance_setup_window");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)dlsym(module, "P3D_instance_setup_window");  
   P3D_instance_has_property = (P3D_instance_has_property_func *)dlsym(module, "P3D_instance_has_property");  
   P3D_instance_has_property = (P3D_instance_has_property_func *)dlsym(module, "P3D_instance_has_property");  
@@ -186,7 +189,8 @@ load_plugin(const string &p3d_plugin_filename) {
   // Ensure that all of the function pointers have been found.
   // Ensure that all of the function pointers have been found.
   if (P3D_initialize == NULL ||
   if (P3D_initialize == NULL ||
       P3D_free_string == NULL ||
       P3D_free_string == NULL ||
-      P3D_create_instance == NULL ||
+      P3D_new_instance == NULL ||
+      P3D_instance_start == NULL ||
       P3D_instance_finish == NULL ||
       P3D_instance_finish == NULL ||
       P3D_instance_setup_window == NULL ||
       P3D_instance_setup_window == NULL ||
       P3D_instance_has_property == NULL ||
       P3D_instance_has_property == NULL ||
@@ -236,7 +240,8 @@ unload_plugin() {
   
   
   P3D_initialize = NULL;
   P3D_initialize = NULL;
   P3D_free_string = NULL;
   P3D_free_string = NULL;
-  P3D_create_instance = NULL;
+  P3D_new_instance = NULL;
+  P3D_instance_start = NULL;
   P3D_instance_finish = NULL;
   P3D_instance_finish = NULL;
   P3D_instance_has_property = NULL;
   P3D_instance_has_property = NULL;
   P3D_instance_get_property = NULL;
   P3D_instance_get_property = NULL;

+ 2 - 1
direct/src/plugin/load_plugin.h

@@ -22,7 +22,8 @@ using namespace std;
 
 
 extern P3D_initialize_func *P3D_initialize;
 extern P3D_initialize_func *P3D_initialize;
 extern P3D_free_string_func *P3D_free_string;
 extern P3D_free_string_func *P3D_free_string;
-extern P3D_create_instance_func *P3D_create_instance;
+extern P3D_new_instance_func *P3D_new_instance;
+extern P3D_instance_start_func *P3D_instance_start;
 extern P3D_instance_finish_func *P3D_instance_finish;
 extern P3D_instance_finish_func *P3D_instance_finish;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 extern P3D_instance_has_property_func *P3D_instance_has_property;
 extern P3D_instance_has_property_func *P3D_instance_has_property;

+ 11 - 0
direct/src/plugin/p3dInstance.I

@@ -70,3 +70,14 @@ inline const string &P3DInstance::
 get_python_version() const {
 get_python_version() const {
   return _python_version;
   return _python_version;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::is_started
+//       Access: Public
+//  Description: Returns true if this instance has already been
+//               started within some session, false otherwise.
+////////////////////////////////////////////////////////////////////
+inline bool P3DInstance::
+is_started() const {
+  return (_session != NULL);
+}

+ 49 - 34
direct/src/plugin/p3dInstance.cxx

@@ -29,28 +29,19 @@ int P3DInstance::_next_instance_id = 0;
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 P3DInstance::
 P3DInstance::
-P3DInstance(P3D_request_ready_func *func, void *user_data,
-            const string &p3d_filename, 
-            const P3D_token tokens[], size_t num_tokens) :
-  _func(func),
-  _fparams(p3d_filename, tokens, num_tokens)
+P3DInstance(P3D_request_ready_func *func, void *user_data) :
+  _func(func)
 {
 {
   _user_data = user_data;
   _user_data = user_data;
   _request_pending = false;
   _request_pending = false;
+  _got_fparams = false;
+  _got_wparams = false;
 
 
   _instance_id = _next_instance_id;
   _instance_id = _next_instance_id;
   ++_next_instance_id;
   ++_next_instance_id;
 
 
   INIT_LOCK(_request_lock);
   INIT_LOCK(_request_lock);
 
 
-  // For the moment, all sessions will be unique.
-  P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
-  ostringstream strm;
-  strm << inst_mgr->get_unique_session_index();
-  _session_key = strm.str();
-
-  _python_version = "python24";
-
   _session = NULL;
   _session = NULL;
   _requested_stop = false;
   _requested_stop = false;
 }
 }
@@ -80,6 +71,29 @@ P3DInstance::
   // download is still running?  Who will crash when this happens?
   // download is still running?  Who will crash when this happens?
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::set_fparams
+//       Access: Public
+//  Description: Sets up the initial file parameters for the instance.
+//               Normally this is only called once.
+////////////////////////////////////////////////////////////////////
+void P3DInstance::
+set_fparams(const P3DFileParams &fparams) {
+  _got_fparams = true;
+  _fparams = fparams;
+
+  // This also sets up some internal data based on the contents of the
+  // above file and the associated tokens.
+
+  // For the moment, all sessions will be unique.
+  P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+  ostringstream strm;
+  strm << inst_mgr->get_unique_session_index();
+  _session_key = strm.str();
+
+  _python_version = "python24";
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::set_wparams
 //     Function: P3DInstance::set_wparams
 //       Access: Public
 //       Access: Public
@@ -89,21 +103,23 @@ P3DInstance::
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DInstance::
 void P3DInstance::
 set_wparams(const P3DWindowParams &wparams) {
 set_wparams(const P3DWindowParams &wparams) {
-  assert(_session != NULL);
+  _got_wparams = true;
   _wparams = wparams;
   _wparams = wparams;
 
 
-  TiXmlDocument *doc = new TiXmlDocument;
-  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", "");
-  TiXmlElement *xcommand = new TiXmlElement("command");
-  xcommand->SetAttribute("cmd", "setup_window");
-  xcommand->SetAttribute("id", get_instance_id());
-  TiXmlElement *xwparams = _wparams.make_xml();
-
-  doc->LinkEndChild(decl);
-  doc->LinkEndChild(xcommand);
-  xcommand->LinkEndChild(xwparams);
-
-  _session->send_command(doc);
+  if (_session != NULL) {
+    TiXmlDocument *doc = new TiXmlDocument;
+    TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", "");
+    TiXmlElement *xcommand = new TiXmlElement("command");
+    xcommand->SetAttribute("cmd", "setup_window");
+    xcommand->SetAttribute("id", get_instance_id());
+    TiXmlElement *xwparams = _wparams.make_xml();
+    
+    doc->LinkEndChild(decl);
+    doc->LinkEndChild(xcommand);
+    xcommand->LinkEndChild(xwparams);
+
+    _session->send_command(doc);
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -153,9 +169,7 @@ set_property(const string &property_name, const string &value) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool P3DInstance::
 bool P3DInstance::
 has_request() {
 has_request() {
-  nout << "has_request called, getting lock\n" << flush;
   ACQUIRE_LOCK(_request_lock);
   ACQUIRE_LOCK(_request_lock);
-  nout << "got lock\n" << flush;
   bool any_requests = !_pending_requests.empty();
   bool any_requests = !_pending_requests.empty();
   RELEASE_LOCK(_request_lock);
   RELEASE_LOCK(_request_lock);
   return any_requests;
   return any_requests;
@@ -174,11 +188,8 @@ P3D_request *P3DInstance::
 get_request() {
 get_request() {
   P3D_request *result = NULL;
   P3D_request *result = NULL;
   ACQUIRE_LOCK(_request_lock);
   ACQUIRE_LOCK(_request_lock);
-  nout << "P3DInstance::get_request() called on " << this
-       << ", " << _pending_requests.size() << " requests in queue\n";
   if (!_pending_requests.empty()) {
   if (!_pending_requests.empty()) {
     result = _pending_requests.front();
     result = _pending_requests.front();
-    nout << "popped request " << result << "\n";
     _pending_requests.pop_front();
     _pending_requests.pop_front();
     _request_pending = !_pending_requests.empty();
     _request_pending = !_pending_requests.empty();
   }
   }
@@ -195,7 +206,6 @@ get_request() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DInstance::
 void P3DInstance::
 add_request(P3D_request *request) {
 add_request(P3D_request *request) {
-  nout << "adding request " << request << " in " << this << "\n";
   assert(request->_instance == this);
   assert(request->_instance == this);
 
 
   ACQUIRE_LOCK(_request_lock);
   ACQUIRE_LOCK(_request_lock);
@@ -204,11 +214,9 @@ add_request(P3D_request *request) {
   RELEASE_LOCK(_request_lock);
   RELEASE_LOCK(_request_lock);
 
 
   // Asynchronous notification for anyone who cares.
   // Asynchronous notification for anyone who cares.
-  nout << "request_ready, calling " << (void *)_func << "\n" << flush;
   if (_func != NULL) {
   if (_func != NULL) {
     _func(this);
     _func(this);
   }
   }
-  nout << "done calling " << (void *)_func << "\n" << flush;
 
 
   // Synchronous notification for pollers.
   // Synchronous notification for pollers.
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
@@ -342,11 +350,18 @@ request_stop() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 TiXmlElement *P3DInstance::
 TiXmlElement *P3DInstance::
 make_xml() {
 make_xml() {
+  assert(_got_fparams);
+
   TiXmlElement *xinstance = new TiXmlElement("instance");
   TiXmlElement *xinstance = new TiXmlElement("instance");
   xinstance->SetAttribute("id", _instance_id);
   xinstance->SetAttribute("id", _instance_id);
 
 
   TiXmlElement *xfparams = _fparams.make_xml();
   TiXmlElement *xfparams = _fparams.make_xml();
   xinstance->LinkEndChild(xfparams);
   xinstance->LinkEndChild(xfparams);
 
 
+  if (_got_wparams) {
+    TiXmlElement *xwparams = _wparams.make_xml();
+    xinstance->LinkEndChild(xwparams);
+  }
+
   return xinstance;
   return xinstance;
 }
 }

+ 6 - 3
direct/src/plugin/p3dInstance.h

@@ -35,11 +35,10 @@ class P3DPackage;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class P3DInstance : public P3D_instance {
 class P3DInstance : public P3D_instance {
 public:
 public:
-  P3DInstance(P3D_request_ready_func *func, void *user_data,
-              const string &p3d_filename, 
-              const P3D_token tokens[], size_t num_tokens);
+  P3DInstance(P3D_request_ready_func *func, void *user_data);
   ~P3DInstance();
   ~P3DInstance();
 
 
+  void set_fparams(const P3DFileParams &fparams);
   inline const P3DFileParams &get_fparams() const;
   inline const P3DFileParams &get_fparams() const;
 
 
   void set_wparams(const P3DWindowParams &wparams);
   void set_wparams(const P3DWindowParams &wparams);
@@ -68,6 +67,7 @@ public:
   void add_package(P3DPackage *package);
   void add_package(P3DPackage *package);
   
   
   void start_download(P3DDownload *download);
   void start_download(P3DDownload *download);
+  inline bool is_started() const;
   void request_stop();
   void request_stop();
 
 
   TiXmlElement *make_xml();
   TiXmlElement *make_xml();
@@ -75,7 +75,10 @@ public:
 private:
 private:
   P3D_request_ready_func *_func;
   P3D_request_ready_func *_func;
 
 
+  bool _got_fparams;
   P3DFileParams _fparams;
   P3DFileParams _fparams;
+
+  bool _got_wparams;
   P3DWindowParams _wparams;
   P3DWindowParams _wparams;
 
 
   int _instance_id;
   int _instance_id;

+ 23 - 11
direct/src/plugin/p3dInstanceManager.cxx

@@ -112,14 +112,30 @@ initialize() {
 //               indicated startup information.
 //               indicated startup information.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 P3DInstance *P3DInstanceManager::
 P3DInstance *P3DInstanceManager::
-create_instance(P3D_request_ready_func *func,
-                void *user_data,
-                const string &p3d_filename, 
-                const P3D_token tokens[], size_t num_tokens) {
-  P3DInstance *inst = new P3DInstance(func, user_data, p3d_filename, 
-                                      tokens, num_tokens);
+create_instance(P3D_request_ready_func *func, void *user_data) {
+  P3DInstance *inst = new P3DInstance(func, user_data);
   _instances.insert(inst);
   _instances.insert(inst);
 
 
+  return inst;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstanceManager::start_instance
+//       Access: Public
+//  Description: Actually starts the instance running.  Before this
+//               call, the instance is in an indeterminate state.  It
+//               is an error to call this more than once for a
+//               particular instance.
+////////////////////////////////////////////////////////////////////
+bool P3DInstanceManager::
+start_instance(P3DInstance *inst, const string &p3d_filename,
+               const P3D_token tokens[], size_t num_tokens) {
+  if (inst->is_started()) {
+    nout << "Instance started twice: " << inst << "\n";
+    return false;
+  }
+  inst->set_fparams(P3DFileParams(p3d_filename, tokens, num_tokens));
+
   P3DSession *session;
   P3DSession *session;
   Sessions::iterator si = _sessions.find(inst->get_session_key());
   Sessions::iterator si = _sessions.find(inst->get_session_key());
   if (si == _sessions.end()) {
   if (si == _sessions.end()) {
@@ -132,7 +148,7 @@ create_instance(P3D_request_ready_func *func,
 
 
   session->start_instance(inst);
   session->start_instance(inst);
 
 
-  return inst;
+  return inst->is_started();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -171,16 +187,12 @@ finish_instance(P3DInstance *inst) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 P3DInstance *P3DInstanceManager::
 P3DInstance *P3DInstanceManager::
 check_request() {
 check_request() {
-  nout << "check_request\n" << flush;
   Instances::iterator ii;
   Instances::iterator ii;
   for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
   for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
     P3DInstance *inst = (*ii);
     P3DInstance *inst = (*ii);
-    cerr << "  checking request for " << inst << "\n" << flush;
     if (inst->has_request()) {
     if (inst->has_request()) {
-      cerr << "    true\n" << flush;
       return inst;
       return inst;
     }
     }
-    cerr << "    false\n" << flush;
   }
   }
 
 
   return NULL;
   return NULL;

+ 4 - 6
direct/src/plugin/p3dInstanceManager.h

@@ -44,13 +44,11 @@ public:
   inline const string &get_platform() const;
   inline const string &get_platform() const;
 
 
   P3DInstance *
   P3DInstance *
-  create_instance(P3D_request_ready_func *func,
-                  void *user_data,
-                  const string &p3d_filename, 
-                  const P3D_token tokens[], size_t num_tokens);
+  create_instance(P3D_request_ready_func *func, void *user_data);
 
 
-  void
-  finish_instance(P3DInstance *inst);
+  bool start_instance(P3DInstance *inst, const string &p3d_filename,
+                      const P3D_token tokens[], size_t num_tokens);
+  void finish_instance(P3DInstance *inst);
 
 
   P3DInstance *check_request();
   P3DInstance *check_request();
   void wait_request();
   void wait_request();

+ 15 - 1
direct/src/plugin/p3dPythonRun.cxx

@@ -292,6 +292,11 @@ start_instance(P3DCInstance *inst, TiXmlElement *xinstance) {
   if (xfparams != (TiXmlElement *)NULL) {
   if (xfparams != (TiXmlElement *)NULL) {
     set_p3d_filename(inst, xfparams);
     set_p3d_filename(inst, xfparams);
   }
   }
+
+  TiXmlElement *xwparams = xinstance->FirstChildElement("wparams");
+  if (xwparams != (TiXmlElement *)NULL) {
+    setup_window(inst, xwparams);
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -377,8 +382,17 @@ setup_window(int id, TiXmlElement *xwparams) {
     return;
     return;
   }
   }
 
 
-  //  P3DCInstance *inst = (*ii).second;
+  P3DCInstance *inst = (*ii).second;
+  setup_window(inst, xwparams);
+}
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DPythonRun::setup_window
+//       Access: Private
+//  Description: Sets the window parameters for the indicated instance.
+////////////////////////////////////////////////////////////////////
+void P3DPythonRun::
+setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
   string window_type;
   string window_type;
   const char *window_type_c = xwparams->Attribute("window_type");
   const char *window_type_c = xwparams->Attribute("window_type");
   if (window_type_c != NULL) {
   if (window_type_c != NULL) {

+ 1 - 0
direct/src/plugin/p3dPythonRun.h

@@ -73,6 +73,7 @@ private:
   void terminate_instance(int id);
   void terminate_instance(int id);
   void set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams);
   void set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams);
   void setup_window(int id, TiXmlElement *xwparams);
   void setup_window(int id, TiXmlElement *xwparams);
+  void setup_window(P3DCInstance *inst, TiXmlElement *xwparams);
   
   
   void terminate_session();
   void terminate_session();
 
 

+ 5 - 5
direct/src/plugin/p3dSession.cxx

@@ -49,15 +49,15 @@ P3DSession(P3DInstance *inst) {
 
 
   _output_filename = inst->get_fparams().lookup_token("output_filename");
   _output_filename = inst->get_fparams().lookup_token("output_filename");
 
 
+  _panda3d_callback = NULL;
+
+  INIT_LOCK(_instances_lock);
+
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
 
 
   _panda3d = inst_mgr->get_package("panda3d", "dev", "Panda3D");
   _panda3d = inst_mgr->get_package("panda3d", "dev", "Panda3D");
-  inst->add_package(_panda3d);
-
-  _panda3d_callback = NULL;
   _python_root_dir = _panda3d->get_package_dir();
   _python_root_dir = _panda3d->get_package_dir();
-
-  INIT_LOCK(_instances_lock);
+  inst->add_package(_panda3d);
 }
 }
 
 
 
 

+ 4 - 1
direct/src/plugin/p3d_lock.h

@@ -32,11 +32,14 @@
 // Posix case
 // Posix case
 #include <pthread.h>
 #include <pthread.h>
 
 
+// We declare this to be a recursive lock, since we might make a
+// request_ready call from within the API, which in turn is allowed to
+// call back into the API.
 #define LOCK pthread_mutex_t
 #define LOCK pthread_mutex_t
 #define INIT_LOCK(lock) { \
 #define INIT_LOCK(lock) { \
     pthread_mutexattr_t attr; \
     pthread_mutexattr_t attr; \
     pthread_mutexattr_init(&attr); \
     pthread_mutexattr_init(&attr); \
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); \
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
     int result = pthread_mutex_init(&(lock), &attr);        \
     int result = pthread_mutex_init(&(lock), &attr);        \
     pthread_mutexattr_destroy(&attr); \
     pthread_mutexattr_destroy(&attr); \
   }
   }

+ 14 - 11
direct/src/plugin/p3d_plugin.cxx

@@ -69,19 +69,26 @@ P3D_free_string(char *string) {
 }
 }
 
 
 P3D_instance *
 P3D_instance *
-P3D_create_instance(P3D_request_ready_func *func,
-                    void *user_data,
-                    const char *p3d_filename, 
-                    const P3D_token tokens[], size_t num_tokens) {
+P3D_new_instance(P3D_request_ready_func *func, void *user_data) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   ACQUIRE_LOCK(_lock);
   ACQUIRE_LOCK(_lock);
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+  P3DInstance *result = inst_mgr->create_instance(func, user_data);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+bool
+P3D_instance_start(P3D_instance *instance, const char *p3d_filename, 
+                   const P3D_token tokens[], size_t num_tokens) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   if (p3d_filename == NULL) {
   if (p3d_filename == NULL) {
     p3d_filename = "";
     p3d_filename = "";
   }
   }
-
-  P3DInstance *result = 
-    inst_mgr->create_instance(func, user_data, p3d_filename, tokens, num_tokens);
+  ACQUIRE_LOCK(_lock);
+  P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+  bool result = inst_mgr->start_instance
+    ((P3DInstance *)instance, p3d_filename, tokens, num_tokens);
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
   return result;
   return result;
 }
 }
@@ -149,9 +156,7 @@ P3D_request *
 P3D_instance_get_request(P3D_instance *instance) {
 P3D_instance_get_request(P3D_instance *instance) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   ACQUIRE_LOCK(_lock);
   ACQUIRE_LOCK(_lock);
-  nout << "P3D_instance_get_request(" << instance << ")\n";
   P3D_request *result = ((P3DInstance *)instance)->get_request();
   P3D_request *result = ((P3DInstance *)instance)->get_request();
-  nout << "  result = " << result << "\n" << flush;
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
   return result;
   return result;
 }
 }
@@ -163,8 +168,6 @@ P3D_check_request(bool wait) {
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3D_instance *inst = inst_mgr->check_request();
   P3D_instance *inst = inst_mgr->check_request();
 
 
-  nout << "P3D_instance_check_request, inst = " << inst << "\n";
-
   if (inst != NULL || !wait) {
   if (inst != NULL || !wait) {
     RELEASE_LOCK(_lock);
     RELEASE_LOCK(_lock);
     return inst;
     return inst;

+ 25 - 18
direct/src/plugin/p3d_plugin.h

@@ -118,7 +118,7 @@ typedef struct {
 
 
   /* an opaque pointer the host may use to store private data that the
   /* an opaque pointer the host may use to store private data that the
      plugin does not interpret.  This pointer can be directly set, or
      plugin does not interpret.  This pointer can be directly set, or
-     it can be initialized in the P3D_create_instance() call. */
+     it can be initialized in the P3D_new_instance() call. */
   void *_user_data;
   void *_user_data;
 
 
   /* Additional opaque data may be stored here. */
   /* Additional opaque data may be stored here. */
@@ -168,10 +168,10 @@ typedef enum {
 } P3D_window_type;
 } P3D_window_type;
 
 
 
 
-/* This function pointer must be passed to P3D_create_instance(),
-   below.  The host must pass in a pointer to a valid function in the
-   host's address space, or NULL.  If not NULL, this function will be
-   called asynchronously by the plugin when the plugin needs to make a
+/* This function pointer must be passed to P3D_new_instance(), below.
+   The host must pass in a pointer to a valid function in the host's
+   address space, or NULL.  If not NULL, this function will be called
+   asynchronously by the plugin when the plugin needs to make a
    request from the host.  After this notification has been received,
    request from the host.  After this notification has been received,
    the host should call P3D_instance_get_request() (at its
    the host should call P3D_instance_get_request() (at its
    convenience) to retrieve the actual plugin request.  If the host
    convenience) to retrieve the actual plugin request.  If the host
@@ -199,17 +199,26 @@ typedef struct {
 
 
 /* This function creates a new Panda3D instance.  
 /* This function creates a new Panda3D instance.  
 
 
-   For p3d_filename pass the name of a file on disk that contains the
-   contents of the p3d file that should be launched within the
-   instance.  If this is empty or NULL, the "src" token (below) will
-   be downloaded instead.
-
    The user_data pointer is any arbitrary pointer value; it will be
    The user_data pointer is any arbitrary pointer value; it will be
    copied into the _user_data member of the new P3D_instance object.
    copied into the _user_data member of the new P3D_instance object.
    This pointer is intended for the host to use to store private data
    This pointer is intended for the host to use to store private data
    associated with each instance; the plugin will not do anything with
    associated with each instance; the plugin will not do anything with
    this data.
    this data.
 
 
+ */
+
+typedef P3D_instance *
+P3D_new_instance_func(P3D_request_ready_func *func, void *user_data);
+
+/* This function should be called at some point after
+   P3D_new_instance(); it actually starts the instance running.
+   Before this call, the instance will be in an indeterminate state.
+
+   For p3d_filename pass the name of a file on disk that contains the
+   contents of the p3d file that should be launched within the
+   instance.  If this is empty or NULL, the "src" token (below) will
+   be downloaded instead.
+
    For tokens, pass an array of P3D_token elements (above), which
    For tokens, pass an array of P3D_token elements (above), which
    correspond to the user-supplied keyword/value pairs that may appear
    correspond to the user-supplied keyword/value pairs that may appear
    in the embed token within the HTML syntax; the host is responsible
    in the embed token within the HTML syntax; the host is responsible
@@ -229,13 +238,10 @@ typedef struct {
        output is written to the standard error output, which may be
        output is written to the standard error output, which may be
        NULL on a gui application.
        NULL on a gui application.
 
 
- */
-
-typedef P3D_instance *
-P3D_create_instance_func(P3D_request_ready_func *func,
-                         void *user_data,
-                         const char *p3d_filename, 
-                         const P3D_token tokens[], size_t num_tokens);
+   The return value is true on success, false on failure. */
+typedef bool
+P3D_instance_start_func(P3D_instance *instance, const char *p3d_filename, 
+                        const P3D_token tokens[], size_t num_tokens);
 
 
 
 
 /* Call this function to interrupt a particular instance and stop it
 /* Call this function to interrupt a particular instance and stop it
@@ -467,7 +473,8 @@ P3D_instance_feed_url_stream_func(P3D_instance *instance, int unique_id,
 /* Define all of the actual prototypes for the above functions. */
 /* Define all of the actual prototypes for the above functions. */
 EXPCL_P3D_PLUGIN P3D_initialize_func P3D_initialize;
 EXPCL_P3D_PLUGIN P3D_initialize_func P3D_initialize;
 EXPCL_P3D_PLUGIN P3D_free_string_func P3D_free_string;
 EXPCL_P3D_PLUGIN P3D_free_string_func P3D_free_string;
-EXPCL_P3D_PLUGIN P3D_create_instance_func P3D_create_instance;
+EXPCL_P3D_PLUGIN P3D_new_instance_func P3D_new_instance;
+EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
 EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
 EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 EXPCL_P3D_PLUGIN P3D_instance_has_property_func P3D_instance_has_property;
 EXPCL_P3D_PLUGIN P3D_instance_has_property_func P3D_instance_has_property;

+ 12 - 9
direct/src/plugin_npapi/ppInstance.cxx

@@ -253,7 +253,7 @@ url_notify(const char *url, NPReason reason, void *notifyData) {
     break;
     break;
   }
   }
   
   
-  //  delete req;
+  delete req;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -333,7 +333,8 @@ stream_as_file(NPStream *stream, const char *fname) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void PPInstance::
 void PPInstance::
 handle_request(P3D_request *request) {
 handle_request(P3D_request *request) {
-  logfile << "handle_request: " << request << "\n";
+  logfile << "handle_request: " << request << ", " << request->_instance
+          << " within " << this << ", " << _p3d_inst << "\n" << flush;
   assert(request->_instance == _p3d_inst);
   assert(request->_instance == _p3d_inst);
 
 
   bool handled = false;
   bool handled = false;
@@ -401,15 +402,17 @@ create_instance() {
     return;
     return;
   }
   }
 
 
-  const P3D_token *tokens = NULL;
-  if (!_tokens.empty()) {
-    tokens = &_tokens[0];
-  }
-
-  _p3d_inst = P3D_create_instance
-    (request_ready, this, _p3d_filename.c_str(), tokens, _tokens.size());
+  logfile << "within " << this << ", creating new instance\n" << flush;
+  _p3d_inst = P3D_new_instance(request_ready, this);
+  logfile << "within " << this << ", created new instance " << _p3d_inst 
+          << "\n" << flush;
 
 
   if (_p3d_inst != NULL) {
   if (_p3d_inst != NULL) {
+    const P3D_token *tokens = NULL;
+    if (!_tokens.empty()) {
+      tokens = &_tokens[0];
+    }
+    P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
     send_window();
     send_window();
   }
   }
 }
 }

+ 6 - 4
direct/src/plugin_standalone/panda3d.cxx

@@ -261,11 +261,13 @@ create_instance(const string &arg, P3D_window_type window_type,
     os_p3d_filename = p3d_filename.to_os_specific();
     os_p3d_filename = p3d_filename.to_os_specific();
   } 
   } 
 
 
-  P3D_instance *inst = P3D_create_instance
-    (NULL, NULL, os_p3d_filename.c_str(), tokens, num_tokens);
+  P3D_instance *inst = P3D_new_instance(NULL, NULL);
 
 
-  P3D_instance_setup_window
-    (inst, window_type, win_x, win_y, win_width, win_height, parent_window);
+  if (inst != NULL) {
+    P3D_instance_setup_window
+      (inst, window_type, win_x, win_y, win_width, win_height, parent_window);
+    P3D_instance_start(inst, os_p3d_filename.c_str(), tokens, num_tokens);
+  }
 
 
   return inst;
   return inst;
 }
 }