7#ifndef PXR_BASE_TF_PY_IDENTITY_H
8#define PXR_BASE_TF_PY_IDENTITY_H
12#include "pxr/base/tf/api.h"
13#include "pxr/base/tf/pyLock.h"
23#include "pxr/external/boost/python/handle.hpp"
25#include "pxr/base/tf/hashmap.h"
29namespace PXR_BOOST_NAMESPACE {
namespace python {
32template <
template <
class>
class X,
class Y>
33struct pointee< PXR_NS::TfWeakPtrFacade<X, Y> > {
39struct pointee< PXR_NS::
TfRefPtr<T> > {
45PXR_NAMESPACE_OPEN_SCOPE
47struct Tf_PyIdentityHelper
52 static void Set(
void const *
id, PyObject *obj);
57 static PyObject *Get(
void const *
id);
60 static void Erase(
void const *
id);
65 static void Acquire(
void const *
id);
70 static void Release(
void const *
id);
75void Tf_PyReleasePythonIdentity(Ptr
const &ptr, PyObject *obj)
77 Tf_PySetPythonIdentity(ptr, obj);
78 Tf_PyIdentityHelper::Release(ptr.GetUniqueIdentifier());
81void Tf_PyOwnershipRefBaseUniqueChanged(
TfRefBase const *refBase,
84struct Tf_PyOwnershipPtrMap
86 typedef TfHashMap<TfRefBase const *, void const *, TfHash>
89 static void Insert(
TfRefBase *refBase,
void const *uniqueId);
91 static void const *Lookup(
TfRefBase const *refBase);
95 static _CacheType _cache;
107template <
class Ptr,
typename Enable =
void>
108struct Tf_PyOwnershipHelper {
109 template <
typename U>
110 static void Add(U
const &,
const void *, PyObject *) {}
111 template <
typename U>
112 static void Remove(U
const &, PyObject *) {}
115template <
typename Ptr>
116struct Tf_PyOwnershipHelper<Ptr,
118 std::is_same<TfRefPtr<typename Ptr::DataType>, Ptr>::value &&
119 std::is_base_of<TfRefBase, typename Ptr::DataType>::value>>
121 static void Add(Ptr ptr,
const void *uniqueId, PyObject *self) {
128 pxr_boost::python::handle<> capsule(
130 new Ptr(ptr),
"refptr",
131 +[](PyObject* capsule) {
132 void* heldPtr = PyCapsule_GetPointer(capsule,
"refptr");
133 delete static_cast<Ptr*
>(heldPtr);
136 int ret = PyObject_SetAttrString(self,
"__owner", capsule.get());
139 TF_WARN(
"Could not set __owner attribute on python object!");
145 static_cast<TfRefBase *
>(get_pointer(ptr));
146 Tf_PyOwnershipPtrMap::Insert(refBase, uniqueId);
149 static void Remove(Ptr ptr, PyObject *obj) {
159 if (PyObject_HasAttrString(obj,
"__owner")) {
168 Tf_PyOwnershipPtrMap::Erase(get_pointer(ptr));
170 if (PyObject_DelAttrString(obj,
"__owner") == -1) {
172 TF_WARN(
"Undeletable __owner attribute on python object!");
183template <
typename Ptr>
184struct Tf_PyIsRefPtr {
185 static const bool value =
false;
190 static const bool value =
true;
195std::enable_if_t<Tf_PyIsRefPtr<Ptr>::value>
196Tf_PySetPythonIdentity(Ptr
const &, PyObject *)
201std::enable_if_t<!Tf_PyIsRefPtr<Ptr>::value>
202Tf_PySetPythonIdentity(Ptr
const &ptr, PyObject *obj)
204 if (ptr.GetUniqueIdentifier()) {
205 Tf_PyIdentityHelper::Set(ptr.GetUniqueIdentifier(), obj);
208 ptr.EnableExtraNotification();
213PyObject *Tf_PyGetPythonIdentity(Ptr
const &ptr)
215 PyObject *ret = Tf_PyIdentityHelper::Get(ptr.GetUniqueIdentifier());
220void Tf_PyRemovePythonOwnership(Ptr
const &t, PyObject *obj)
222 Tf_PyOwnershipHelper<Ptr>::Remove(t, obj);
226void Tf_PyAddPythonOwnership(Ptr
const &t,
const void *uniqueId, PyObject *obj)
228 Tf_PyOwnershipHelper<Ptr>::Add(t, uniqueId, obj);
231PXR_NAMESPACE_CLOSE_SCOPE
Low-level utilities for informing users of various internal and external diagnostic conditions.
Miscellaneous Utilities for dealing with script.
Convenience class for accessing the Python Global Interpreter Lock.
Enable a concrete base class for use with TfRefPtr.
Reference-counted smart pointer utility class.
Demangle C++ typenames generated by the typeid() facility.
#define TF_AXIOM(cond)
Aborts if the condition cond is not met.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
#define TF_WARN(...)
Issue a warning, but continue execution.
Safely compare C++ RTTI type structures.
Definitions of basic string utilities in tf.
Pointer storage with deletion detection.