|
@@ -632,73 +632,6 @@ copy_subgraph(Thread *current_thread) const {
|
|
|
return r_copy_subgraph(inst_map, current_thread);
|
|
return r_copy_subgraph(inst_map, current_thread);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::__copy__
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: A special Python method that is invoked by
|
|
|
|
|
-// copy.copy(node). Unlike the PandaNode copy
|
|
|
|
|
-// constructor, which creates a new node without
|
|
|
|
|
-// children, this shares child pointers (essentially
|
|
|
|
|
-// making every child an instance). This is intended to
|
|
|
|
|
-// simulate the behavior of copy.copy() for other
|
|
|
|
|
-// objects.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-PT(PandaNode) PandaNode::
|
|
|
|
|
-__copy__() const {
|
|
|
|
|
- Thread *current_thread = Thread::get_current_thread();
|
|
|
|
|
-
|
|
|
|
|
- PT(PandaNode) node_dupe = make_copy();
|
|
|
|
|
-
|
|
|
|
|
- Children children = get_children(current_thread);
|
|
|
|
|
- int num_children = children.get_num_children();
|
|
|
|
|
-
|
|
|
|
|
- for (int i = 0; i < num_children; ++i) {
|
|
|
|
|
- node_dupe->add_child(children.get_child(i), children.get_child_sort(i));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return node_dupe;
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::__deepcopy__
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: A special Python method that is invoked by
|
|
|
|
|
-// copy.deepcopy(node). This calls copy_subgraph()
|
|
|
|
|
-// unless the node is already present in the provided
|
|
|
|
|
-// dictionary.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-PyObject *PandaNode::
|
|
|
|
|
-__deepcopy__(PyObject *self, PyObject *memo) const {
|
|
|
|
|
- IMPORT_THIS struct Dtool_PyTypedObject Dtool_PandaNode;
|
|
|
|
|
-
|
|
|
|
|
- // Borrowed reference.
|
|
|
|
|
- PyObject *dupe = PyDict_GetItem(memo, self);
|
|
|
|
|
- if (dupe != NULL) {
|
|
|
|
|
- // Already in the memo dictionary.
|
|
|
|
|
- Py_INCREF(dupe);
|
|
|
|
|
- return dupe;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- PT(PandaNode) node_dupe = copy_subgraph();
|
|
|
|
|
-
|
|
|
|
|
- // DTool_CreatePyInstanceTyped() steals a C++ reference.
|
|
|
|
|
- node_dupe->ref();
|
|
|
|
|
- dupe = DTool_CreatePyInstanceTyped
|
|
|
|
|
- ((void *)node_dupe.p(), Dtool_PandaNode, true, false,
|
|
|
|
|
- node_dupe->get_type_index());
|
|
|
|
|
-
|
|
|
|
|
- if (PyDict_SetItem(memo, self, dupe) != 0) {
|
|
|
|
|
- Py_DECREF(dupe);
|
|
|
|
|
- return NULL;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return dupe;
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: PandaNode::count_num_descendants
|
|
// Function: PandaNode::count_num_descendants
|
|
|
// Access: Published
|
|
// Access: Published
|
|
@@ -1509,118 +1442,6 @@ clear_tag(const string &key, Thread *current_thread) {
|
|
|
mark_bam_modified();
|
|
mark_bam_modified();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::set_python_tag
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: Associates an arbitrary Python object with a
|
|
|
|
|
-// user-defined key which is stored on the node. This
|
|
|
|
|
-// is similar to set_tag(), except it can store any
|
|
|
|
|
-// Python object instead of just a string. However, the
|
|
|
|
|
-// Python object is not recorded to a bam file.
|
|
|
|
|
-//
|
|
|
|
|
-// Each unique key stores a different string value.
|
|
|
|
|
-// There is no effective limit on the number of
|
|
|
|
|
-// different keys that may be stored or on the length of
|
|
|
|
|
-// any one key's value.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-void PandaNode::
|
|
|
|
|
-set_python_tag(const string &key, PyObject *value) {
|
|
|
|
|
- Thread *current_thread = Thread::get_current_thread();
|
|
|
|
|
- int pipeline_stage = current_thread->get_pipeline_stage();
|
|
|
|
|
- nassertv(pipeline_stage == 0);
|
|
|
|
|
-
|
|
|
|
|
- CDWriter cdata(_cycler);
|
|
|
|
|
- Py_XINCREF(value);
|
|
|
|
|
-
|
|
|
|
|
- pair<PythonTagData::iterator, bool> result;
|
|
|
|
|
- result = cdata->_python_tag_data.insert(PythonTagData::value_type(key, value));
|
|
|
|
|
-
|
|
|
|
|
- if (!result.second) {
|
|
|
|
|
- // The insert was unsuccessful; that means the key was already
|
|
|
|
|
- // present in the map. In this case, we should decrement the
|
|
|
|
|
- // original value's reference count and replace it with the new
|
|
|
|
|
- // object.
|
|
|
|
|
- PythonTagData::iterator ti = result.first;
|
|
|
|
|
- PyObject *old_value = (*ti).second;
|
|
|
|
|
- Py_XDECREF(old_value);
|
|
|
|
|
- (*ti).second = value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Even though the python tag isn't recorded in the bam stream?
|
|
|
|
|
- mark_bam_modified();
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::get_python_tag
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: Retrieves the Python object that was previously
|
|
|
|
|
-// set on this node for the particular key, if any. If
|
|
|
|
|
-// no value has been previously set, returns None.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-PyObject *PandaNode::
|
|
|
|
|
-get_python_tag(const string &key) const {
|
|
|
|
|
- CDReader cdata(_cycler);
|
|
|
|
|
- PythonTagData::const_iterator ti;
|
|
|
|
|
- ti = cdata->_python_tag_data.find(key);
|
|
|
|
|
- if (ti != cdata->_python_tag_data.end()) {
|
|
|
|
|
- PyObject *result = (*ti).second;
|
|
|
|
|
- Py_XINCREF(result);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
- Py_INCREF(Py_None);
|
|
|
|
|
- return Py_None;
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::has_python_tag
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: Returns true if a Python object has been defined on
|
|
|
|
|
-// this node for the particular key (even if that object
|
|
|
|
|
-// is None), or false if no object has been set.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-bool PandaNode::
|
|
|
|
|
-has_python_tag(const string &key) const {
|
|
|
|
|
- CDReader cdata(_cycler);
|
|
|
|
|
- PythonTagData::const_iterator ti;
|
|
|
|
|
- ti = cdata->_python_tag_data.find(key);
|
|
|
|
|
- return (ti != cdata->_python_tag_data.end());
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: PandaNode::clear_python_tag
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: Removes the Python object defined for this key on
|
|
|
|
|
-// this particular node. After a call to
|
|
|
|
|
-// clear_python_tag(), has_python_tag() will return
|
|
|
|
|
-// false for the indicated key.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-void PandaNode::
|
|
|
|
|
-clear_python_tag(const string &key) {
|
|
|
|
|
- Thread *current_thread = Thread::get_current_thread();
|
|
|
|
|
- int pipeline_stage = current_thread->get_pipeline_stage();
|
|
|
|
|
- nassertv(pipeline_stage == 0);
|
|
|
|
|
-
|
|
|
|
|
- CDWriter cdata(_cycler, current_thread);
|
|
|
|
|
- PythonTagData::iterator ti;
|
|
|
|
|
- ti = cdata->_python_tag_data.find(key);
|
|
|
|
|
- if (ti != cdata->_python_tag_data.end()) {
|
|
|
|
|
- PyObject *value = (*ti).second;
|
|
|
|
|
- Py_XDECREF(value);
|
|
|
|
|
- cdata->_python_tag_data.erase(ti);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Even though the python tag isn't recorded in the bam stream?
|
|
|
|
|
- mark_bam_modified();
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: PandaNode::copy_tags
|
|
// Function: PandaNode::copy_tags
|
|
|
// Access: Published
|
|
// Access: Published
|
|
@@ -1743,80 +1564,6 @@ get_tag_keys(vector_string &keys) const {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-#ifdef HAVE_PYTHON
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: Filename::get_python_tag_keys
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: Fills the given vector up with the
|
|
|
|
|
-// list of Python tags on this PandaNode.
|
|
|
|
|
-//
|
|
|
|
|
-// It is the user's responsibility to ensure that the
|
|
|
|
|
-// keys vector is empty before making this call;
|
|
|
|
|
-// otherwise, the new files will be appended to it.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-void PandaNode::
|
|
|
|
|
-get_python_tag_keys(vector_string &keys) const {
|
|
|
|
|
- CDReader cdata(_cycler);
|
|
|
|
|
- if (!cdata->_python_tag_data.empty()) {
|
|
|
|
|
- PythonTagData::const_iterator ti = cdata->_python_tag_data.begin();
|
|
|
|
|
- while (ti != cdata->_python_tag_data.end()) {
|
|
|
|
|
- keys.push_back((*ti).first);
|
|
|
|
|
- ++ti;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: Filename::get_tag_keys
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: This variant on get_tag_keys returns
|
|
|
|
|
-// a Python list of strings.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-PyObject *PandaNode::
|
|
|
|
|
-get_tag_keys() const {
|
|
|
|
|
- vector_string keys;
|
|
|
|
|
- get_tag_keys(keys);
|
|
|
|
|
-
|
|
|
|
|
- PyObject *result = PyList_New(keys.size());
|
|
|
|
|
- for (size_t i = 0; i < keys.size(); ++i) {
|
|
|
|
|
- const string &tag_name = keys[i];
|
|
|
|
|
-#if PY_MAJOR_VERSION >= 3
|
|
|
|
|
- PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size());
|
|
|
|
|
-#else
|
|
|
|
|
- PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size());
|
|
|
|
|
-#endif
|
|
|
|
|
- PyList_SET_ITEM(result, i, str);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return result;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-// Function: Filename::get_python_tag_keys
|
|
|
|
|
-// Access: Published
|
|
|
|
|
-// Description: This variant on get_python_tag_keys returns
|
|
|
|
|
-// a Python list of strings.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-PyObject *PandaNode::
|
|
|
|
|
-get_python_tag_keys() const {
|
|
|
|
|
- vector_string keys;
|
|
|
|
|
- get_python_tag_keys(keys);
|
|
|
|
|
-
|
|
|
|
|
- PyObject *result = PyList_New(keys.size());
|
|
|
|
|
- for (size_t i = 0; i < keys.size(); ++i) {
|
|
|
|
|
- const string &tag_name = keys[i];
|
|
|
|
|
-#if PY_MAJOR_VERSION >= 3
|
|
|
|
|
- PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size());
|
|
|
|
|
-#else
|
|
|
|
|
- PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size());
|
|
|
|
|
-#endif
|
|
|
|
|
- PyList_SET_ITEM(result, i, str);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return result;
|
|
|
|
|
-}
|
|
|
|
|
-#endif // HAVE_PYTHON
|
|
|
|
|
-
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: PandaNode::compare_tags
|
|
// Function: PandaNode::compare_tags
|
|
|
// Access: Published
|
|
// Access: Published
|