24 #ifndef PXR_BASE_TF_PY_NOTICE_WRAPPER_H
25 #define PXR_BASE_TF_PY_NOTICE_WRAPPER_H
31 #include "pxr/base/tf/type.h"
32 #include "pxr/base/tf/pyLock.h"
33 #include "pxr/base/tf/pyObjectFinder.h"
34 #include "pxr/base/tf/wrapTypeHelpers.h"
36 #include <boost/mpl/and.hpp>
37 #include <boost/mpl/if.hpp>
38 #include <boost/mpl/or.hpp>
39 #include <boost/python/bases.hpp>
40 #include <boost/python/class.hpp>
41 #include <boost/python/extract.hpp>
42 #include <boost/python/handle.hpp>
44 #include <type_traits>
48 PXR_NAMESPACE_OPEN_SCOPE
50 struct Tf_PyNoticeObjectGenerator {
51 typedef Tf_PyNoticeObjectGenerator This;
52 typedef boost::python::object (*MakeObjectFunc)(
TfNotice const &);
56 static void Register() {
58 (*_generators)[
typeid(T).name()] = This::_Generate<T>;
62 TF_API
static boost::python::object Invoke(
TfNotice const &n);
67 static boost::python::object _Generate(
TfNotice const &n) {
69 return boost::python::object(static_cast<T const &>(n));
72 static MakeObjectFunc _Lookup(
TfNotice const &n);
78 struct TfPyNoticeWrapperBase :
public TfType::PyPolymorphicBase {
79 TF_API
virtual ~TfPyNoticeWrapperBase();
80 virtual boost::python::handle<> GetNoticePythonObject()
const = 0;
83 template <
class Notice>
84 struct Tf_PyNoticeObjectFinder :
public Tf_PyObjectFinderBase {
85 virtual ~Tf_PyNoticeObjectFinder() {}
86 virtual boost::python::object Find(
void const *objPtr)
const {
87 using namespace boost::python;
89 Notice
const *wrapper =
static_cast<Notice
const *
>(objPtr);
90 return wrapper ? object(wrapper->GetNoticePythonObject()) :
object();
94 template <
typename NoticeType,
typename BaseType>
95 struct TfPyNoticeWrapper :
public NoticeType,
public TfPyNoticeWrapperBase {
97 static_assert(std::is_base_of<TfNotice, NoticeType>::value
98 || std::is_same<TfNotice, NoticeType>::value,
99 "Notice type must be derived from or equal to TfNotice.");
101 static_assert(std::is_base_of<TfNotice, BaseType>::value
102 || std::is_same<TfNotice, BaseType>::value,
103 "BaseType type must be derived from or equal to TfNotice.");
105 static_assert(std::is_base_of<BaseType, NoticeType>::value
106 || (std::is_same<NoticeType, TfNotice>::value
107 && std::is_same<BaseType, TfNotice>::value),
108 "BaseType type must be a base of notice, unless both "
109 "BaseType and Notice type are equal to TfNotice.");
113 typedef TfPyNoticeWrapper<NoticeType, BaseType> This;
117 typedef typename boost::mpl::if_<
118 boost::is_same<NoticeType, TfNotice>
119 , boost::python::bases<>, boost::python::bases<BaseType> >::type Bases;
121 typedef boost::python::class_<NoticeType, This, Bases> ClassType;
123 static ClassType Wrap(std::string
const &name = std::string()) {
124 std::string wrappedName = name;
125 if (wrappedName.empty()) {
127 wrappedName = TfType::Find<NoticeType>().GetTypeName();
131 Tf_PyNoticeObjectGenerator::Register<NoticeType>();
132 Tf_RegisterPythonObjectFinderInternal
133 (
typeid(TfPyNoticeWrapper),
134 new Tf_PyNoticeObjectFinder<TfPyNoticeWrapper>);
135 return ClassType(wrappedName.c_str(), boost::python::no_init)
140 virtual boost::python::handle<> GetNoticePythonObject()
const {
142 return boost::python::handle<>(boost::python::borrowed(_self));
147 template <
typename... Args>
148 TfPyNoticeWrapper(PyObject *
self, Args... args)
149 : NoticeType(args...)
157 #define TF_INSTANTIATE_NOTICE_WRAPPER(T, Base) \
158 TF_REGISTRY_FUNCTION(TfType) \
160 TfType::Define< TfPyNoticeWrapper<T, Base>, \
161 TfType::Bases<Base> >(); \
164 PXR_NAMESPACE_CLOSE_SCOPE
166 #endif // PXR_BASE_TF_PY_NOTICE_WRAPPER_H
The base class for objects used to notify interested parties (listeners) when events have occurred...
TF_API std::string TfStringGetSuffix(const std::string &name, char delimiter= '.')
Returns the suffix of a string.
A boost.python visitor that associates the Python class object created by the wrapping with the TfTyp...
Definitions of basic string utilities in tf.
Create or return a previously created object instance of global data.