From 6a2cb24ecf490491efa7f27189cfbc16dc264d12 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 2 Mar 2010 01:39:34 +0000 Subject: [PATCH] RT_forget_package --- direct/src/p3d/AppRunner.py | 3 + direct/src/p3d/HostInfo.py | 3 + direct/src/plugin/p3dHost.cxx | 1 + direct/src/plugin/p3dInstance.cxx | 71 ++++++++++++++++++++++-- direct/src/plugin/p3dInstanceManager.cxx | 2 + direct/src/plugin/p3dPythonRun.cxx | 19 +++++++ direct/src/plugin/p3dSession.cxx | 3 +- direct/src/plugin/p3d_plugin.h | 20 ++++++- 8 files changed, 115 insertions(+), 7 deletions(-) diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index e44a0195cd..e49acddc0c 100644 --- a/direct/src/p3d/AppRunner.py +++ b/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, diff --git a/direct/src/p3d/HostInfo.py b/direct/src/p3d/HostInfo.py index a4dbf1e735..cd61c6c047 100644 --- a/direct/src/p3d/HostInfo.py +++ b/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. diff --git a/direct/src/plugin/p3dHost.cxx b/direct/src/plugin/p3dHost.cxx index 7eb588dca7..0a0b7dac51 100644 --- a/direct/src/plugin/p3dHost.cxx +++ b/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]; diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index bee7dfa2a3..7d2b1201bb 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/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"; } diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index fd21c7d301..0bfcc1a6cf 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/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 diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 12c979f736..eb78bad696 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/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()); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index ff8a5cec37..23dc4d827a 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/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) { diff --git a/direct/src/plugin/p3d_plugin.h b/direct/src/plugin/p3d_plugin.h index 7ab00a0708..c7d6bc614d 100644 --- a/direct/src/plugin/p3d_plugin.h +++ b/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;