HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyNoticeWrapper.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_PY_NOTICE_WRAPPER_H
8 #define PXR_BASE_TF_PY_NOTICE_WRAPPER_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/base/tf/notice.h"
13 #include "pxr/base/tf/staticData.h"
14 #include "pxr/base/tf/type.h"
15 #include "pxr/base/tf/pyLock.h"
18 
19 #include "pxr/external/boost/python/bases.hpp"
20 #include "pxr/external/boost/python/class.hpp"
21 #include "pxr/external/boost/python/extract.hpp"
22 #include "pxr/external/boost/python/handle.hpp"
23 
24 #include <type_traits>
25 #include <map>
26 #include <string>
27 
29 
33 
34  // Register the generator for notice type T.
35  template <typename T>
36  static void Register() {
37  // XXX this stuff should be keyed directly off TfType now
38  (*_generators)[typeid(T).name()] = This::_Generate<T>;
39  }
40 
41  // Produce a pxr_boost::python::object for the correct derived type of \a n.
43 
44 private:
45 
46  template <typename T>
47  static pxr_boost::python::object _Generate(TfNotice const &n) {
48  // Python locking is left to the caller.
49  return pxr_boost::python::object(static_cast<T const &>(n));
50  }
51 
52  static MakeObjectFunc _Lookup(TfNotice const &n);
53 
55 
56 };
57 
58 struct TfPyNoticeWrapperBase : public TfType::PyPolymorphicBase {
60  virtual pxr_boost::python::handle<> GetNoticePythonObject() const = 0;
61 };
62 
63 template <class Notice>
66  virtual pxr_boost::python::object Find(void const *objPtr) const {
67  using namespace pxr_boost::python;
68  TfPyLock lock;
69  Notice const *wrapper = static_cast<Notice const *>(objPtr);
70  return wrapper ? object(wrapper->GetNoticePythonObject()) : object();
71  }
72 };
73 
74 template <typename NoticeType, typename BaseType>
75 struct TfPyNoticeWrapper : public NoticeType, public TfPyNoticeWrapperBase {
76 private:
79  "Notice type must be derived from or equal to TfNotice.");
80 
83  "BaseType type must be derived from or equal to TfNotice.");
84 
88  "BaseType type must be a base of notice, unless both "
89  "BaseType and Notice type are equal to TfNotice.");
90 
91 public:
92 
94 
95  // If Notice is really TfNotice, then this is the root of the hierarchy and
96  // bases is empty, otherwise bases contains the base class.
98  pxr_boost::python::bases<>,
99  pxr_boost::python::bases<BaseType>>;
100 
101  typedef pxr_boost::python::class_<NoticeType, This, Bases> ClassType;
102 
103  static ClassType Wrap(std::string const &name = std::string()) {
104  std::string wrappedName = name;
105  if (wrappedName.empty()) {
106  // Assume they want the last bit of a qualified name.
107  wrappedName = TfType::Find<NoticeType>().GetTypeName();
108  if (!TfStringGetSuffix(wrappedName, ':').empty())
109  wrappedName = TfStringGetSuffix(wrappedName, ':');
110  }
111  Tf_PyNoticeObjectGenerator::Register<NoticeType>();
113  (typeid(TfPyNoticeWrapper),
115  return ClassType(wrappedName.c_str(), pxr_boost::python::no_init)
116  .def(TfTypePythonClass());
117  }
118 
119  // Implement the base class's virtual method.
120  virtual pxr_boost::python::handle<> GetNoticePythonObject() const {
121  TfPyLock lock;
122  return pxr_boost::python::handle<>(pxr_boost::python::borrowed(_self));
123  }
124 
125  // Arbitrary argument constructor (with a leading PyObject *) which
126  // forwards to the base Notice class's constructor.
127  template <typename... Args>
128  TfPyNoticeWrapper(PyObject *self, Args... args)
129  : NoticeType(args...)
130  , _self(self) {}
131 
132 private:
133  PyObject *_self;
134 
135 };
136 
137 #define TF_INSTANTIATE_NOTICE_WRAPPER(T, Base) \
138 TF_REGISTRY_FUNCTION(TfType) \
139 { \
140  TfType::Define< TfPyNoticeWrapper<T, Base>, \
141  TfType::Bases<Base> >(); \
142 }
143 
145 
146 #endif // PXR_BASE_TF_PY_NOTICE_WRAPPER_H
#define TF_API
Definition: api.h:23
TF_API std::string TfStringGetSuffix(const std::string &name, char delimiter= '.')
GLsizei const GLfloat * value
Definition: glcorearb.h:824
TfPyNoticeWrapper(PyObject *self, Args...args)
virtual ~Tf_PyNoticeObjectFinder()
TF_API void Tf_RegisterPythonObjectFinderInternal(std::type_info const &type, Tf_PyObjectFinderBase const *finder)
TfPyNoticeWrapper< NoticeType, BaseType > This
static TF_API pxr_boost::python::object Invoke(TfNotice const &n)
GLdouble n
Definition: glcorearb.h:2008
static ClassType Wrap(std::string const &name=std::string())
Tf_PyNoticeObjectGenerator This
GLuint const GLchar * name
Definition: glcorearb.h:786
virtual pxr_boost::python::handle GetNoticePythonObject() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
pxr_boost::python::class_< NoticeType, This, Bases > ClassType
pxr_boost::python::object(* MakeObjectFunc)(TfNotice const &)
virtual pxr_boost::python::handle GetNoticePythonObject() const =0
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
**If you just want to fire and args
Definition: thread.h:618
virtual TF_API ~TfPyNoticeWrapperBase()
virtual pxr_boost::python::object Find(void const *objPtr) const
std::conditional_t< std::is_same< NoticeType, TfNotice >::value, pxr_boost::python::bases<>, pxr_boost::python::bases< BaseType >> Bases