24 #ifndef PXR_BASE_TF_PY_IDENTITY_H 25 #define PXR_BASE_TF_PY_IDENTITY_H 29 #include "pxr/base/tf/api.h" 30 #include "pxr/base/tf/pyLock.h" 40 #include <boost/python/class.hpp> 41 #include <boost/python/handle.hpp> 42 #include <boost/python/object.hpp> 43 #include <boost/type_traits/is_base_of.hpp> 44 #include <boost/utility.hpp> 46 #include "pxr/base/tf/hashmap.h" 50 namespace boost {
namespace python {
53 template <
template <
class>
class X,
class Y>
54 struct pointee< PXR_NS::TfWeakPtrFacade<X, Y> > {
60 struct pointee< PXR_NS::
TfRefPtr<T> > {
66 PXR_NAMESPACE_OPEN_SCOPE
68 struct Tf_PyIdentityHelper
73 static void Set(
void const *
id, PyObject *obj);
78 static PyObject *Get(
void const *
id);
81 static void Erase(
void const *
id);
86 static void Acquire(
void const *
id);
91 static void Release(
void const *
id);
96 void Tf_PyReleasePythonIdentity(Ptr
const &ptr, PyObject *obj)
98 Tf_PySetPythonIdentity(ptr, obj);
99 Tf_PyIdentityHelper::Release(ptr.GetUniqueIdentifier());
102 void Tf_PyOwnershipRefBaseUniqueChanged(
TfRefBase const *refBase,
105 struct Tf_PyOwnershipPtrMap
107 typedef TfHashMap<TfRefBase const *, void const *, TfHash>
110 static void Insert(
TfRefBase *refBase,
void const *uniqueId);
112 static void const *Lookup(
TfRefBase const *refBase);
116 static _CacheType _cache;
128 template <
class Ptr,
typename Enable =
void>
129 struct Tf_PyOwnershipHelper {
130 template <
typename U>
131 static void Add(U
const &,
const void *, PyObject *) {}
132 template <
typename U>
133 static void Remove(U
const &, PyObject *) {}
136 template <
typename Ptr>
137 struct Tf_PyOwnershipHelper<Ptr,
138 typename boost::enable_if<
139 boost::mpl::and_<boost::is_same<TfRefPtr<typename Ptr::DataType>, Ptr>,
140 boost::is_base_of<TfRefBase, typename Ptr::DataType> > >::type>
142 struct _RefPtrHolder {
143 static boost::python::object
144 Get(Ptr
const &refptr) {
147 return boost::python::object(_RefPtrHolder(refptr));
149 static void _WrapIfNecessary() {
151 if (
TfPyIsNone(TfPyGetClassObject<_RefPtrHolder>())) {
158 boost::python::class_<_RefPtrHolder>(name.c_str(),
159 boost::python::no_init);
163 explicit _RefPtrHolder(Ptr
const &refptr) : _refptr(refptr) {}
167 static void Add(Ptr ptr,
const void *uniqueId, PyObject *
self) {
172 int ret = PyObject_SetAttrString(
self,
"__owner",
173 _RefPtrHolder::Get(ptr).ptr());
176 TF_WARN(
"Could not set __owner attribute on python object!");
182 static_cast<TfRefBase *>(get_pointer(ptr));
183 Tf_PyOwnershipPtrMap::Insert(refBase, uniqueId);
186 static void Remove(Ptr ptr, PyObject *obj) {
196 if (PyObject_HasAttrString(obj,
"__owner")) {
205 Tf_PyOwnershipPtrMap::Erase(get_pointer(ptr));
207 if (PyObject_DelAttrString(obj,
"__owner") == -1) {
209 TF_WARN(
"Undeletable __owner attribute on python object!");
217 #endif // doxygen -- see comment above. 220 template <
typename Ptr>
221 struct Tf_PyIsRefPtr {
222 static const bool value =
false;
225 template <
typename T>
226 struct Tf_PyIsRefPtr<
TfRefPtr<T> > {
227 static const bool value =
true;
232 typename boost::enable_if<Tf_PyIsRefPtr<Ptr> >::type
233 Tf_PySetPythonIdentity(Ptr
const &, PyObject *)
238 typename boost::disable_if<Tf_PyIsRefPtr<Ptr> >::type
239 Tf_PySetPythonIdentity(Ptr
const &ptr, PyObject *obj)
241 if (ptr.GetUniqueIdentifier()) {
242 Tf_PyIdentityHelper::Set(ptr.GetUniqueIdentifier(), obj);
245 ptr.EnableExtraNotification();
250 PyObject *Tf_PyGetPythonIdentity(Ptr
const &ptr)
252 PyObject *ret = Tf_PyIdentityHelper::Get(ptr.GetUniqueIdentifier());
257 void Tf_PyRemovePythonOwnership(Ptr
const &t, PyObject *obj)
259 Tf_PyOwnershipHelper<Ptr>::Remove(t, obj);
263 void Tf_PyAddPythonOwnership(Ptr
const &t,
const void *uniqueId, PyObject *obj)
265 Tf_PyOwnershipHelper<Ptr>::Add(t, uniqueId, obj);
268 PXR_NAMESPACE_CLOSE_SCOPE
270 #endif // PXR_BASE_TF_PY_IDENTITY_H Safely compare C++ RTTI type structures.
#define TF_WARN(...)
Issue a warning, but continue execution.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
Return demangled RTTI-generated type name.
Definitions of basic string utilities in tf.
Low-level utilities for informing users of various internal and external diagnostic conditions.
Miscellaneous Utilities for dealing with script.
Pointer storage with deletion detection.
Demangle C++ typenames generated by the typeid() facility.
Enable a concrete base class for use with TfRefPtr.
Convenience class for accessing the Python Global Interpreter Lock.
TF_API bool TfPyIsNone(boost::python::object const &obj)
Return true iff obj is None.
#define TF_AXIOM(cond)
Aborts if the condition cond is not met.
Reference-counted smart pointer utility class.
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
Replaces all occurrences of string from with to in source.