HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyMapEditProxy.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_USD_SDF_PY_MAP_EDIT_PROXY_H
25 #define PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
26 
27 /// \file sdf/pyMapEditProxy.h
28 
29 #include "pxr/pxr.h"
31 #include "pxr/base/arch/demangle.h"
32 #include "pxr/base/tf/iterator.h"
33 #include "pxr/base/tf/pyUtils.h"
35 #include <hboost/python.hpp>
36 
38 
39 template <class T>
41 public:
42  typedef T Type;
43  typedef typename Type::key_type key_type;
44  typedef typename Type::mapped_type mapped_type;
45  typedef typename Type::value_type value_type;
46  typedef typename Type::iterator iterator;
47  typedef typename Type::const_iterator const_iterator;
49 
51  {
52  TfPyWrapOnce<Type>(&This::_Wrap);
53  }
54 
55 private:
56  typedef std::pair<key_type, mapped_type> pair_type;
57 
58  struct _ExtractItem {
59  static hboost::python::object Get(const const_iterator& i)
60  {
61  return hboost::python::make_tuple(i->first, i->second);
62  }
63  };
64 
65  struct _ExtractKey {
66  static hboost::python::object Get(const const_iterator& i)
67  {
68  return hboost::python::object(i->first);
69  }
70  };
71 
72  struct _ExtractValue {
73  static hboost::python::object Get(const const_iterator& i)
74  {
75  return hboost::python::object(i->second);
76  }
77  };
78 
79  template <class E>
80  class _Iterator {
81  public:
82  _Iterator(const hboost::python::object& object) :
83  _object(object),
84  _owner(hboost::python::extract<const Type&>(object)),
85  _cur(_owner.begin()),
86  _end(_owner.end())
87  {
88  // Do nothing
89  }
90 
91  _Iterator<E> GetCopy() const
92  {
93  return *this;
94  }
95 
96  hboost::python::object GetNext()
97  {
98  if (_cur == _end) {
99  TfPyThrowStopIteration("End of MapEditProxy iteration");
100  }
101  hboost::python::object result = E::Get(_cur);
102  ++_cur;
103  return result;
104  }
105 
106  private:
107  hboost::python::object _object;
108  const Type& _owner;
109  const_iterator _cur;
110  const_iterator _end;
111  };
112 
113  static void _Wrap()
114  {
115  using namespace hboost::python;
116 
117  std::string name = _GetName();
118 
119  scope thisScope =
120  class_<Type>(name.c_str())
121  .def("__repr__", &This::_GetRepr)
122  .def("__str__", &This::_GetStr)
123  .def("__len__", &Type::size)
124  .def("__getitem__", &This::_GetItem)
125  .def("__setitem__", &This::_SetItem)
126  .def("__delitem__", &This::_DelItem)
127  .def("__contains__", &This::_HasKey)
128  .def("__iter__", &This::_GetKeyIterator)
129  .def("values", &This::_GetValueIterator)
130  .def("keys", &This::_GetKeyIterator)
131  .def("items", &This::_GetItemIterator)
132  .def("clear", &Type::clear)
133  .def("get", &This::_PyGet)
134  .def("get", &This::_PyGetDefault)
135  .def("pop", &This::_Pop)
136  .def("popitem", &This::_PopItem)
137  .def("setdefault", &This::_SetDefault)
138  .def("update", &This::_UpdateDict)
139  .def("update", &This::_UpdateList)
140  .def("copy", &This::_Copy)
141  .add_property("expired", &Type::IsExpired)
142  .def("__bool__", &This::_IsValid)
143  .def(self == self)
144  .def(self != self)
145  ;
146 
147  class_<_Iterator<_ExtractItem> >
148  ((name + "_Iterator").c_str(), no_init)
149  .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
150  .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
151  ;
152 
153  class_<_Iterator<_ExtractKey> >
154  ((name + "_KeyIterator").c_str(), no_init)
155  .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
156  .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
157  ;
158 
159  class_<_Iterator<_ExtractValue> >
160  ((name + "_ValueIterator").c_str(), no_init)
161  .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
162  .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
163  ;
164  }
165 
166  static std::string _GetName()
167  {
168  std::string name = "MapEditProxy_" +
169  ArchGetDemangled<typename Type::Type>();
170  name = TfStringReplace(name, " ", "_");
171  name = TfStringReplace(name, ",", "_");
172  name = TfStringReplace(name, "::", "_");
173  name = TfStringReplace(name, "<", "_");
174  name = TfStringReplace(name, ">", "_");
175  return name;
176  }
177 
178  static std::string _GetRepr(const Type& x)
179  {
181  if (x) {
182  arg = TfStringPrintf("<%s>", x._Location().c_str());
183  }
184  else {
185  arg = "<invalid>";
186  }
187  return TF_PY_REPR_PREFIX + _GetName() + "(" + arg + ")";
188  }
189 
190  static std::string _GetStr(const Type& x)
191  {
192  std::string result("{");
193  if (x && ! x.empty()) {
194  const_iterator i = x.begin(), n = x.end();
195  result += TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
196  while (++i != n) {
197  result +=", " + TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
198  }
199  }
200  result += "}";
201  return result;
202  }
203 
204  static mapped_type _GetItem(const Type& x, const key_type& key)
205  {
206  const_iterator i = x.find(key);
207  if (i == x.end()) {
209  return mapped_type();
210  }
211  else {
212  return i->second;
213  }
214  }
215 
216  static void _SetItem(Type& x, const key_type& key, const mapped_type& value)
217  {
218  std::pair<typename Type::iterator, bool> i =
219  x.insert(value_type(key, value));
220  if (! i.second && i.first != typename Type::iterator()) {
221  i.first->second = value;
222  }
223  }
224 
225  static void _DelItem(Type& x, const key_type& key)
226  {
227  x.erase(key);
228  }
229 
230  static bool _HasKey(const Type& x, const key_type& key)
231  {
232  return x.count(key) != 0;
233  }
234 
235  static _Iterator<_ExtractItem>
236  _GetItemIterator(const hboost::python::object& x)
237  {
238  return _Iterator<_ExtractItem>(x);
239  }
240 
241  static _Iterator<_ExtractKey>
242  _GetKeyIterator(const hboost::python::object& x)
243  {
244  return _Iterator<_ExtractKey>(x);
245  }
246 
247  static _Iterator<_ExtractValue>
248  _GetValueIterator(const hboost::python::object& x)
249  {
250  return _Iterator<_ExtractValue>(x);
251  }
252 
253  static hboost::python::object _PyGet(const Type& x, const key_type& key)
254  {
255  const_iterator i = x.find(key);
256  return i == x.end() ? hboost::python::object() :
257  hboost::python::object(i->second);
258  }
259 
260  static mapped_type _PyGetDefault(const Type& x, const key_type& key,
261  const mapped_type& def)
262  {
263  const_iterator i = x.find(key);
264  return i == x.end() ? def : i->second;
265  }
266 
267  template <class E>
268  static hboost::python::list _Get(const Type& x)
269  {
270  hboost::python::list result;
271  for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
272  result.append(E::Get(i));
273  }
274  return result;
275  }
276 
277  static mapped_type _Pop(Type& x, const key_type& key)
278  {
279  iterator i = x.find(key);
280  if (i == x.end()) {
282  return mapped_type();
283  }
284  else {
285  mapped_type result = i->second;
286  x.erase(i);
287  return result;
288  }
289  }
290 
291  static hboost::python::tuple _PopItem(Type& x)
292  {
293  if (x.empty()) {
294  TfPyThrowKeyError("MapEditProxy is empty");
295  return hboost::python::tuple();
296  }
297  else {
298  iterator i = x.begin();
299  value_type result = *i;
300  x.erase(i);
301  return hboost::python::make_tuple(result.first, result.second);
302  }
303  }
304 
305  static mapped_type _SetDefault(Type& x, const key_type& key,
306  const mapped_type& def)
307  {
308  const_iterator i = x.find(key);
309  if (i != x.end()) {
310  return i->second;
311  }
312  else {
313  return x[key] = def;
314  }
315  }
316 
317  static void _Update(Type& x, const std::vector<pair_type>& values)
318  {
319  SdfChangeBlock block;
320  TF_FOR_ALL(i, values) {
321  x[i->first] = i->second;
322  }
323  }
324 
325  static void _UpdateDict(Type& x, const hboost::python::dict& d)
326  {
327  _UpdateList(x, d.items());
328  }
329 
330  static void _UpdateList(Type& x, const hboost::python::list& pairs)
331  {
332  using namespace hboost::python;
333 
334  std::vector<pair_type> values;
335  for (int i = 0, n = len(pairs); i != n; ++i) {
336  values.push_back(pair_type(
337  extract<key_type>(pairs[i][0])(),
338  extract<mapped_type>(pairs[i][1])()));
339  }
340  _Update(x, values);
341  }
342 
343  static void _Copy(Type& x, const typename Type::Type& other)
344  {
345  x = other;
346  }
347 
348  static bool _IsValid(const Type& x)
349  {
350  return static_cast<bool>(x);
351  }
352 };
353 
355 
356 #endif // PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
TF_API std::string TfStringPrintf(const char *fmt,...)
Type::mapped_type mapped_type
SdfPyWrapMapEditProxy< Type > This
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Type::key_type key_type
TF_API void TfPyThrowStopIteration(const char *msg)
**But if you need a result
Definition: thread.h:613
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
uint64 value_type
Definition: GA_PrimCompat.h:29
std::string TfPyRepr(T const &t)
Definition: pyUtils.h:180
OIIO_FORCEINLINE bool extract(const vbool4 &a)
Definition: simd.h:3426
GLdouble n
Definition: glcorearb.h:2008
Type::iterator iterator
GLuint GLuint end
Definition: glcorearb.h:475
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLenum GLint x
Definition: glcorearb.h:409
GLsizeiptr size
Definition: glcorearb.h:664
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
Type::const_iterator const_iterator
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TF_API void TfPyThrowKeyError(const char *msg)
Definition: core.h:1131
#define TF_FOR_ALL(iter, c)
Definition: iterator.h:390
#define TF_PY_REPR_PREFIX
Definition: pyUtils.h:59
Type::value_type value_type
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:558