Browse Source

gobj: more efficient pickling support for InternalName

Rather than going through the TypedWritable/bam route, this encodes InternalNames in a more compact and efficient manner.
rdb 5 years ago
parent
commit
f192a0cdb6

+ 2 - 0
panda/src/gobj/internalName.h

@@ -97,6 +97,8 @@ PUBLISHED:
   // These versions are exposed to Python, which have additional logic to map
   // from Python interned strings.
   EXTENSION(static PT(InternalName) make(PyObject *str));
+
+  EXTENSION(PyObject *__reduce__() const);
 #endif
 
 public:

+ 12 - 0
panda/src/gobj/internalName_ext.cxx

@@ -17,6 +17,8 @@ using std::string;
 
 #ifdef HAVE_PYTHON
 
+extern struct Dtool_PyTypedObject Dtool_InternalName;
+
 /**
  * This extension method serves to allow coercion of Python interned strings
  * to InternalName objects more efficiently by storing a mapping between
@@ -88,7 +90,17 @@ make(PyObject *str) {
     InternalName::_py_intern_table.insert(std::make_pair((PyObject *)str, iname.p()));
     return iname;
   }
+}
 
+/**
+ * This special Python method is implemented to provide support for the pickle
+ * module.
+ */
+PyObject *Extension<InternalName>::
+__reduce__() const {
+  std::string name = _this->get_name();
+  return Py_BuildValue("(N(s#))",
+    PyObject_GetAttrString((PyObject *)&Dtool_InternalName._PyType, "make"), name.c_str(), name.size());
 }
 
 #endif  // HAVE_PYTHON

+ 2 - 0
panda/src/gobj/internalName_ext.h

@@ -30,6 +30,8 @@ template<>
 class Extension<InternalName> : public ExtensionBase<InternalName> {
 public:
   static PT(InternalName) make(PyObject *str);
+
+  PyObject *__reduce__() const;
 };
 
 #endif  // HAVE_PYTHON