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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_PY_NOTICE_WRAPPER_H
25 #define PXR_BASE_TF_PY_NOTICE_WRAPPER_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/base/tf/notice.h"
30 #include "pxr/base/tf/staticData.h"
31 #include "pxr/base/tf/type.h"
32 #include "pxr/base/tf/pyLock.h"
35 
36 #include <hboost/python/bases.hpp>
37 #include <hboost/python/class.hpp>
38 #include <hboost/python/extract.hpp>
39 #include <hboost/python/handle.hpp>
40 
41 #include <type_traits>
42 #include <map>
43 #include <string>
44 
46 
50 
51  // Register the generator for notice type T.
52  template <typename T>
53  static void Register() {
54  // XXX this stuff should be keyed directly off TfType now
55  (*_generators)[typeid(T).name()] = This::_Generate<T>;
56  }
57 
58  // Produce a hboost::python::object for the correct derived type of \a n.
60 
61 private:
62 
63  template <typename T>
64  static hboost::python::object _Generate(TfNotice const &n) {
65  // Python locking is left to the caller.
66  return hboost::python::object(static_cast<T const &>(n));
67  }
68 
69  static MakeObjectFunc _Lookup(TfNotice const &n);
70 
72 
73 };
74 
75 struct TfPyNoticeWrapperBase : public TfType::PyPolymorphicBase {
77  virtual hboost::python::handle<> GetNoticePythonObject() const = 0;
78 };
79 
80 template <class Notice>
83  virtual hboost::python::object Find(void const *objPtr) const {
84  using namespace hboost::python;
85  TfPyLock lock;
86  Notice const *wrapper = static_cast<Notice const *>(objPtr);
87  return wrapper ? object(wrapper->GetNoticePythonObject()) : object();
88  }
89 };
90 
91 template <typename NoticeType, typename BaseType>
92 struct TfPyNoticeWrapper : public NoticeType, public TfPyNoticeWrapperBase {
93 private:
96  "Notice type must be derived from or equal to TfNotice.");
97 
100  "BaseType type must be derived from or equal to TfNotice.");
101 
105  "BaseType type must be a base of notice, unless both "
106  "BaseType and Notice type are equal to TfNotice.");
107 
108 public:
109 
111 
112  // If Notice is really TfNotice, then this is the root of the hierarchy and
113  // bases is empty, otherwise bases contains the base class.
115  hboost::python::bases<>,
116  hboost::python::bases<BaseType>>;
117 
118  typedef hboost::python::class_<NoticeType, This, Bases> ClassType;
119 
121  std::string wrappedName = name;
122  if (wrappedName.empty()) {
123  // Assume they want the last bit of a qualified name.
124  wrappedName = TfType::Find<NoticeType>().GetTypeName();
125  if (!TfStringGetSuffix(wrappedName, ':').empty())
126  wrappedName = TfStringGetSuffix(wrappedName, ':');
127  }
128  Tf_PyNoticeObjectGenerator::Register<NoticeType>();
130  (typeid(TfPyNoticeWrapper),
132  return ClassType(wrappedName.c_str(), hboost::python::no_init)
133  .def(TfTypePythonClass());
134  }
135 
136  // Implement the base class's virtual method.
137  virtual hboost::python::handle<> GetNoticePythonObject() const {
138  TfPyLock lock;
139  return hboost::python::handle<>(hboost::python::borrowed(_self));
140  }
141 
142  // Arbitrary argument constructor (with a leading PyObject *) which
143  // forwards to the base Notice class's constructor.
144  template <typename... Args>
145  TfPyNoticeWrapper(PyObject *self, Args... args)
146  : NoticeType(args...)
147  , _self(self) {}
148 
149 private:
150  PyObject *_self;
151 
152 };
153 
154 #define TF_INSTANTIATE_NOTICE_WRAPPER(T, Base) \
155 TF_REGISTRY_FUNCTION(TfType) \
156 { \
157  TfType::Define< TfPyNoticeWrapper<T, Base>, \
158  TfType::Bases<Base> >(); \
159 }
160 
162 
163 #endif // PXR_BASE_TF_PY_NOTICE_WRAPPER_H
#define TF_API
Definition: api.h:40
TF_API std::string TfStringGetSuffix(const std::string &name, char delimiter= '.')
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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)
hboost::python::class_< NoticeType, This, Bases > ClassType
TfPyNoticeWrapper< NoticeType, BaseType > This
virtual hboost::python::object Find(void const *objPtr) const
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
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
virtual hboost::python::handle GetNoticePythonObject() const
hboost::python::object(* MakeObjectFunc)(TfNotice const &)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
**If you just want to fire and args
Definition: thread.h:609
virtual TF_API ~TfPyNoticeWrapperBase()
static TF_API hboost::python::object Invoke(TfNotice const &n)
std::conditional_t< std::is_same< NoticeType, TfNotice >::value, hboost::python::bases<>, hboost::python::bases< BaseType >> Bases
virtual hboost::python::handle GetNoticePythonObject() const =0