|
|
@@ -0,0 +1,93 @@
|
|
|
+/**
|
|
|
+ * PANDA 3D SOFTWARE
|
|
|
+ * Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
|
+ *
|
|
|
+ * All use of this software is subject to the terms of the revised BSD
|
|
|
+ * license. You should have received a copy of this license along
|
|
|
+ * with this source code in a file named "LICENSE."
|
|
|
+ *
|
|
|
+ * @file eggNode_ext.cxx
|
|
|
+ * @author rdb
|
|
|
+ * @date 2021-01-01
|
|
|
+ */
|
|
|
+
|
|
|
+#include "eggNode_ext.h"
|
|
|
+#include "eggData.h"
|
|
|
+
|
|
|
+#ifdef HAVE_PYTHON
|
|
|
+
|
|
|
+/**
|
|
|
+ * Implements pickle support.
|
|
|
+ */
|
|
|
+PyObject *Extension<EggNode>::
|
|
|
+__reduce__() const {
|
|
|
+ extern struct Dtool_PyTypedObject Dtool_EggNode;
|
|
|
+
|
|
|
+ // Find the parse_egg_node function in this module.
|
|
|
+ PyObject *sys_modules = PyImport_GetModuleDict();
|
|
|
+ nassertr_always(sys_modules != nullptr, nullptr);
|
|
|
+
|
|
|
+ PyObject *module_name = PyObject_GetAttrString((PyObject *)&Dtool_EggNode, "__module__");
|
|
|
+ nassertr_always(module_name != nullptr, nullptr);
|
|
|
+
|
|
|
+ PyObject *module = PyDict_GetItem(sys_modules, module_name);
|
|
|
+ Py_DECREF(module_name);
|
|
|
+ nassertr_always(module != nullptr, nullptr);
|
|
|
+
|
|
|
+ PyObject *func;
|
|
|
+ if (_this->is_of_type(EggData::get_class_type())) {
|
|
|
+ func = PyObject_GetAttrString(module, "parse_egg_data");
|
|
|
+ } else {
|
|
|
+ func = PyObject_GetAttrString(module, "parse_egg_node");
|
|
|
+ }
|
|
|
+ nassertr_always(func != nullptr, nullptr);
|
|
|
+
|
|
|
+ // Get the egg syntax to pass to the parse_egg_node function.
|
|
|
+ std::ostringstream stream;
|
|
|
+ _this->write(stream, INT_MIN);
|
|
|
+ std::string data = stream.str();
|
|
|
+ size_t length = data.size();
|
|
|
+
|
|
|
+ // Trim trailing whitespace.
|
|
|
+ while (length > 0 && isspace(data[length - 1])) {
|
|
|
+ --length;
|
|
|
+ }
|
|
|
+
|
|
|
+ return Py_BuildValue("N(s#)", func, data.data(), (Py_ssize_t)length);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Parses an EggData from the raw egg syntax.
|
|
|
+ */
|
|
|
+PT(EggData) parse_egg_data(const std::string &egg_syntax) {
|
|
|
+ PT(EggData) data = new EggData;
|
|
|
+ data->set_auto_resolve_externals(false);
|
|
|
+
|
|
|
+ std::istringstream in(egg_syntax);
|
|
|
+
|
|
|
+ if (!data->read(in)) {
|
|
|
+ PyErr_Format(PyExc_RuntimeError, "failed to parse egg data");
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ return data;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Parses a single egg node from the raw egg syntax.
|
|
|
+ */
|
|
|
+PT(EggNode) parse_egg_node(const std::string &egg_syntax) {
|
|
|
+ PT(EggData) data = parse_egg_data(egg_syntax);
|
|
|
+ if (data == nullptr) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data->size() != 1) {
|
|
|
+ PyErr_Format(PyExc_RuntimeError, "expected exactly one node");
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ return data->remove_child(data->get_first_child());
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|