Browse Source

RT_forget_package

David Rose 16 years ago
parent
commit
6a2cb24ecf

+ 3 - 0
direct/src/p3d/AppRunner.py

@@ -410,6 +410,9 @@ class AppRunner(DirectObject):
         self.notify.info("Deleting host %s: %s" % (host.hostUrl, host.hostDir))
         self.notify.info("Deleting host %s: %s" % (host.hostUrl, host.hostDir))
         shutil.rmtree(host.hostDir.toOsSpecific(), True)
         shutil.rmtree(host.hostDir.toOsSpecific(), True)
 
 
+        self.sendRequest('forget_package', host.hostUrl, '', '')
+        
+
     def freshenFile(self, host, fileSpec, localPathname):
     def freshenFile(self, host, fileSpec, localPathname):
         """ Ensures that the localPathname is the most current version
         """ Ensures that the localPathname is the most current version
         of the file defined by fileSpec, as offered by host.  If not,
         of the file defined by fileSpec, as offered by host.  If not,

+ 3 - 0
direct/src/p3d/HostInfo.py

@@ -485,6 +485,9 @@ class HostInfo:
         self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
         self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
         shutil.rmtree(package.getPackageDir().toOsSpecific(), True)
         shutil.rmtree(package.getPackageDir().toOsSpecific(), True)
 
 
+        if self.appRunner:
+            self.appRunner.sendRequest('forget_package', self.hostUrl, package.packageName, package.packageVersion or '')
+
     def __determineHostDir(self, hostDirBasename, hostUrl):
     def __determineHostDir(self, hostDirBasename, hostUrl):
         """ Hashes the host URL into a (mostly) unique directory
         """ Hashes the host URL into a (mostly) unique directory
         string, which will be the root of the host's install tree.
         string, which will be the root of the host's install tree.

+ 1 - 0
direct/src/plugin/p3dHost.cxx

@@ -405,6 +405,7 @@ get_package_desc_file(FileSpec &desc_file,              // out
 void P3DHost::
 void P3DHost::
 forget_package(P3DPackage *package, const string &alt_host) {
 forget_package(P3DPackage *package, const string &alt_host) {
   string key = package->get_package_name() + "_" + package->get_package_version();
   string key = package->get_package_name() + "_" + package->get_package_version();
+  nout << "Forgetting package " << key << "\n";
 
 
   PackageMap &package_map = _packages[alt_host];
   PackageMap &package_map = _packages[alt_host];
 
 

+ 67 - 4
direct/src/plugin/p3dInstance.cxx

@@ -743,6 +743,28 @@ get_request() {
         (*func)(data);
         (*func)(data);
       }
       }
       break;
       break;
+
+    case P3D_RT_forget_package:
+      {
+        // We're being asked to forget a particular package.
+        const char *host_url = request->_request._forget_package._host_url;
+        const char *package_name = request->_request._forget_package._package_name;
+        const char *package_version = request->_request._forget_package._package_version;
+        if (package_version == NULL) {
+          package_version = "";
+        }
+
+        P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+        P3DHost *host = inst_mgr->get_host(host_url);
+        if (package_name != NULL) {
+          P3DPackage *package = host->get_package(package_name, package_version);
+          host->forget_package(package);
+        } else {
+          // If a NULL package name is given, forget the whole host.
+          inst_mgr->forget_host(host);
+        }
+      }
+      break;
     }
     }
   }
   }
   
   
@@ -869,18 +891,38 @@ finish_request(P3D_request *request, bool handled) {
     break;
     break;
 
 
   case P3D_RT_get_url:
   case P3D_RT_get_url:
-    free((char *)request->_request._get_url._url);
-    request->_request._get_url._url = NULL;
+    if (request->_request._get_url._url != NULL) {
+      free((char *)request->_request._get_url._url);
+      request->_request._get_url._url = NULL;
+    }
     break;
     break;
 
 
   case P3D_RT_notify:
   case P3D_RT_notify:
-    free((char *)request->_request._notify._message);
-    request->_request._notify._message = NULL;
+    if (request->_request._notify._message != NULL) {
+      free((char *)request->_request._notify._message);
+      request->_request._notify._message = NULL;
+    }
+    break;
+
+  case P3D_RT_forget_package:
+    if (request->_request._forget_package._host_url != NULL) {
+      free((char *)request->_request._forget_package._host_url);
+      request->_request._forget_package._host_url = NULL;
+    }
+    if (request->_request._forget_package._package_name != NULL) {
+      free((char *)request->_request._forget_package._package_name);
+      request->_request._forget_package._package_name = NULL;
+    }
+    if (request->_request._forget_package._package_version != NULL) {
+      free((char *)request->_request._forget_package._package_version);
+      request->_request._forget_package._package_version = NULL;
+    }
     break;
     break;
   }
   }
 
 
   p3d_unref_delete(((P3DInstance *)request->_instance));
   p3d_unref_delete(((P3DInstance *)request->_instance));
   request->_instance = NULL;
   request->_instance = NULL;
+
   delete request;
   delete request;
 }
 }
 
 
@@ -2245,6 +2287,27 @@ make_p3d_request(TiXmlElement *xrequest) {
       request->_instance = NULL;
       request->_instance = NULL;
       request->_request_type = P3D_RT_stop;
       request->_request_type = P3D_RT_stop;
 
 
+    } else if (strcmp(rtype, "forget_package") == 0) {
+      const char *host_url = xrequest->Attribute("host_url");
+      if (host_url != NULL) {
+        // A Python-level request to remove a package from the cache.
+        request = new P3D_request;
+        request->_instance = NULL;
+        request->_request_type = P3D_RT_forget_package;
+        request->_request._forget_package._host_url = strdup(host_url);
+        request->_request._forget_package._package_name = NULL;
+        request->_request._forget_package._package_version = NULL;
+
+        const char *package_name = xrequest->Attribute("package_name");
+        const char *package_version = xrequest->Attribute("package_version");
+        if (package_name != NULL) {
+          request->_request._forget_package._package_name = strdup(package_name);
+          if (package_version != NULL) {
+            request->_request._forget_package._package_version = strdup(package_version);
+          }
+        }
+      }
+
     } else {
     } else {
       nout << "Ignoring request of type " << rtype << "\n";
       nout << "Ignoring request of type " << rtype << "\n";
     }
     }

+ 2 - 0
direct/src/plugin/p3dInstanceManager.cxx

@@ -622,6 +622,8 @@ get_host(const string &host_url) {
 void P3DInstanceManager::
 void P3DInstanceManager::
 forget_host(P3DHost *host) {
 forget_host(P3DHost *host) {
   const string &host_url = host->get_host_url();
   const string &host_url = host->get_host_url();
+
+  nout << "Forgetting host " << host_url << "\n";
   
   
   // Hmm, this is a memory leak.  But we allow it to remain, since
   // Hmm, this is a memory leak.  But we allow it to remain, since
   // it's an unusual circumstance (uninstalling), and it's safer to
   // it's an unusual circumstance (uninstalling), and it's safer to

+ 19 - 0
direct/src/plugin/p3dPythonRun.cxx

@@ -1080,6 +1080,25 @@ py_request_func(PyObject *args) {
     xrequest->SetAttribute("object_id", object_id);
     xrequest->SetAttribute("object_id", object_id);
     write_xml(_pipe_write, &doc, nout);
     write_xml(_pipe_write, &doc, nout);
 
 
+  } else if (strcmp(request_type, "forget_package") == 0) {
+    // A request to the instance to drop a particular package (or
+    // host) from the cache.
+    const char *host_url;
+    const char *package_name;
+    const char *package_version;
+    if (!PyArg_ParseTuple(extra_args, "sss", &host_url, &package_name, &package_version)) {
+      return NULL;
+    }
+
+    xrequest->SetAttribute("host_url", host_url);
+    if (*package_name) {
+      xrequest->SetAttribute("package_name", package_name);
+      if (*package_version) {
+        xrequest->SetAttribute("package_version", package_version);
+      }
+    }
+    write_xml(_pipe_write, &doc, nout);
+
   } else {
   } else {
     string message = string("Unsupported request type: ") + string(request_type);
     string message = string("Unsupported request type: ") + string(request_type);
     PyErr_SetString(PyExc_ValueError, message.c_str());
     PyErr_SetString(PyExc_ValueError, message.c_str());

+ 2 - 1
direct/src/plugin/p3dSession.cxx

@@ -1290,7 +1290,8 @@ rt_thread_run() {
 //     Function: P3DSession::rt_handle_request
 //     Function: P3DSession::rt_handle_request
 //       Access: Private
 //       Access: Private
 //  Description: Processes a single request or notification received
 //  Description: Processes a single request or notification received
-//               from an instance.
+//               from an instance.  This method runs in the read
+//               thread.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DSession::
 void P3DSession::
 rt_handle_request(TiXmlDocument *doc) {
 rt_handle_request(TiXmlDocument *doc) {

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

@@ -767,6 +767,7 @@ typedef enum {
   P3D_RT_notify,
   P3D_RT_notify,
   P3D_RT_refresh,
   P3D_RT_refresh,
   P3D_RT_callback,
   P3D_RT_callback,
+  P3D_RT_forget_package
 } P3D_request_type;
 } P3D_request_type;
 
 
 /* Structures corresponding to the request types in the above enum. */
 /* Structures corresponding to the request types in the above enum. */
@@ -792,8 +793,9 @@ typedef struct {
 } P3D_request_get_url;
 } P3D_request_get_url;
 
 
 /* A general notification.  This is just a message of some event
 /* A general notification.  This is just a message of some event
-   having occurred within the Panda3D instance.  It may be safely
-   ignored.
+   having occurred within the Panda3D instance.  The core API will
+   automatically trigger a JavaScript callback based on this event.
+   It may be safely ignored by the application.
 */
 */
 typedef struct {
 typedef struct {
   const char *_message;
   const char *_message;
@@ -818,6 +820,19 @@ typedef struct {
   void *_data;
   void *_data;
 } P3D_request_callback;
 } P3D_request_callback;
 
 
+/* A forget-package request.  This is called when a Python application
+   wishes to uninstall a specific package (for instance, to clean up
+   disk space).  It is assumed that the application will be
+   responsible for deleting the actual files of the package; this is
+   just an instruction to the core API to remove the indicated package
+   from the in-memory cache.  This is handled internally, and
+   shouldn't be interpreted by the caller. */
+typedef struct {
+  const char *_host_url;
+  const char *_package_name;
+  const char *_package_version;
+} P3D_request_forget_package;
+
 /* This is the overall structure that represents a single request.  It
 /* This is the overall structure that represents a single request.  It
    is returned by P3D_instance_get_request(). */
    is returned by P3D_instance_get_request(). */
 typedef struct {
 typedef struct {
@@ -829,6 +844,7 @@ typedef struct {
     P3D_request_notify _notify;
     P3D_request_notify _notify;
     P3D_request_refresh _refresh;
     P3D_request_refresh _refresh;
     P3D_request_callback _callback;
     P3D_request_callback _callback;
+    P3D_request_forget_package _forget_package;
   } _request;
   } _request;
 } P3D_request;
 } P3D_request;