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))
         shutil.rmtree(host.hostDir.toOsSpecific(), True)
 
+        self.sendRequest('forget_package', host.hostUrl, '', '')
+        
+
     def freshenFile(self, host, fileSpec, localPathname):
         """ Ensures that the localPathname is the most current version
         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()))
         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):
         """ Hashes the host URL into a (mostly) unique directory
         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::
 forget_package(P3DPackage *package, const string &alt_host) {
   string key = package->get_package_name() + "_" + package->get_package_version();
+  nout << "Forgetting package " << key << "\n";
 
   PackageMap &package_map = _packages[alt_host];
 

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

@@ -743,6 +743,28 @@ get_request() {
         (*func)(data);
       }
       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;
 
   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;
 
   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;
   }
 
   p3d_unref_delete(((P3DInstance *)request->_instance));
   request->_instance = NULL;
+
   delete request;
 }
 
@@ -2245,6 +2287,27 @@ make_p3d_request(TiXmlElement *xrequest) {
       request->_instance = NULL;
       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 {
       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::
 forget_host(P3DHost *host) {
   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
   // 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);
     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 {
     string message = string("Unsupported request type: ") + string(request_type);
     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
 //       Access: Private
 //  Description: Processes a single request or notification received
-//               from an instance.
+//               from an instance.  This method runs in the read
+//               thread.
 ////////////////////////////////////////////////////////////////////
 void P3DSession::
 rt_handle_request(TiXmlDocument *doc) {

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

@@ -767,6 +767,7 @@ typedef enum {
   P3D_RT_notify,
   P3D_RT_refresh,
   P3D_RT_callback,
+  P3D_RT_forget_package
 } P3D_request_type;
 
 /* Structures corresponding to the request types in the above enum. */
@@ -792,8 +793,9 @@ typedef struct {
 } P3D_request_get_url;
 
 /* 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 {
   const char *_message;
@@ -818,6 +820,19 @@ typedef struct {
   void *_data;
 } 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
    is returned by P3D_instance_get_request(). */
 typedef struct {
@@ -829,6 +844,7 @@ typedef struct {
     P3D_request_notify _notify;
     P3D_request_refresh _refresh;
     P3D_request_callback _callback;
+    P3D_request_forget_package _forget_package;
   } _request;
 } P3D_request;