HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyListProxy.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_USD_SDF_PY_LIST_PROXY_H
8 #define PXR_USD_SDF_PY_LIST_PROXY_H
9 
10 /// \file sdf/pyListProxy.h
11 
12 #include "pxr/pxr.h"
14 #include "pxr/usd/sdf/listProxy.h"
15 #include "pxr/base/arch/demangle.h"
16 #include "pxr/base/tf/pyLock.h"
17 #include "pxr/base/tf/pyUtils.h"
20 #include <stdexcept>
21 #include "pxr/external/boost/python.hpp"
22 #include "pxr/external/boost/python/slice.hpp"
23 
25 
26 template <class T>
28 public:
29  typedef T Type;
30  typedef typename Type::TypePolicy TypePolicy;
31  typedef typename Type::value_type value_type;
32  typedef typename Type::value_vector_type value_vector_type;
34 
36  {
37  TfPyWrapOnce<Type>(&This::_Wrap);
38  }
39 
40 private:
41  static void _Wrap()
42  {
43  using namespace pxr_boost::python;
44 
45  class_<Type>(_GetName().c_str(), no_init)
46  .def("__str__", &This::_GetStr)
47  .def("__len__", &Type::size)
48  .def("__getitem__", &This::_GetItemIndex)
49  .def("__getitem__", &This::_GetItemSlice)
50  .def("__setitem__", &This::_SetItemIndex)
51  .def("__setitem__", &This::_SetItemSlice)
52  .def("__delitem__", &This::_DelItemIndex)
53  .def("__delitem__", &This::_DelItemSlice)
54  .def("__delitem__", &Type::Remove)
55  .def("count", &Type::Count)
56  .def("copy", &Type::operator value_vector_type,
57  return_value_policy<TfPySequenceToList>())
58  .def("index", &This::_FindIndex)
59  .def("clear", &Type::clear)
60  .def("insert", &This::_Insert)
61  .def("append", &Type::push_back)
62  .def("remove", &Type::Remove)
63  .def("replace", &Type::Replace)
64  .def("ApplyList", &Type::ApplyList)
65  .def("ApplyEditsToList", &This::_ApplyEditsToList)
66  .add_property("expired", &This::_IsExpired)
67  .add_static_property("invalidIndex", &This::_GetInvalidIndex)
68  .def(self == self)
69  .def(self != self)
70  .def(self < self)
71  .def(self <= self)
72  .def(self > self)
73  .def(self >= self)
74  .def(self == other<value_vector_type>())
75  .def(self != other<value_vector_type>())
76  .def(self < other<value_vector_type>())
77  .def(self <= other<value_vector_type>())
78  .def(self > other<value_vector_type>())
79  .def(self >= other<value_vector_type>())
80  ;
81  }
82 
83  static std::string _GetName()
84  {
85  std::string name = "ListProxy_" +
86  ArchGetDemangled<TypePolicy>();
87  name = TfStringReplace(name, " ", "_");
88  name = TfStringReplace(name, ",", "_");
89  name = TfStringReplace(name, "::", "_");
90  name = TfStringReplace(name, "<", "_");
91  name = TfStringReplace(name, ">", "_");
92  return name;
93  }
94 
95  static std::string _GetStr(const Type& x)
96  {
97  return TfPyRepr(static_cast<value_vector_type>(x));
98  }
99 
100  static value_type _GetItemIndex(const Type& x, int index)
101  {
102  return x[TfPyNormalizeIndex(index, x._GetSize(), true)];
103  }
104 
105  static pxr_boost::python::list _GetItemSlice(const Type& x,
106  const pxr_boost::python::slice& index)
107  {
108  using namespace pxr_boost::python;
109 
110  list result;
111 
112  if (x._Validate()) {
113  try {
114  slice::range<typename Type::const_iterator> range =
115  index.get_indicies(x.begin(), x.end());
116  for (; range.start != range.stop; range.start += range.step) {
117  result.append(*range.start);
118  }
119  result.append(*range.start);
120  }
121  catch (const std::invalid_argument&) {
122  // Ignore.
123  }
124  }
125 
126  return result;
127  }
128 
129  static void _SetItemIndex(Type& x, int index, const value_type& value)
130  {
131  x[TfPyNormalizeIndex(index, x._GetSize(), true)] = value;
132  }
133 
134  static void _SetItemSlice(Type& x, const pxr_boost::python::slice& index,
135  const value_vector_type& values)
136  {
137  using namespace pxr_boost::python;
138 
139  if (! x._Validate()) {
140  return;
141  }
142 
143  // Get the range and the number of items in the slice.
144  size_t start, step, count;
145  try {
146  slice::range<typename Type::iterator> range =
147  index.get_indicies(x.begin(), x.end());
148  start = range.start - x.begin();
149  step = range.step;
150  count = 1 + (range.stop - range.start) / range.step;
151  }
152  catch (const std::invalid_argument&) {
153  // Empty range.
154  extract<int> e(index.start());
155  start = e.check() ? TfPyNormalizeIndex(e(), x._GetSize(), true) : 0;
156  step = 0;
157  count = 0;
158  }
159 
160  if (TfPyIsNone(index.step())) {
161  // Replace contiguous sequence with values.
162  x._Edit(start, count, values);
163  }
164  else {
165  // Replace exactly the selected items.
166  if (count != values.size()) {
168  TfStringPrintf("attempt to assign sequence of size %zd "
169  "to extended slice of size %zd",
170  values.size(), count).c_str());
171  }
172  else if (step == 1) {
173  x._Edit(start, count, values);
174  }
175  else {
176  SdfChangeBlock block;
177  for (size_t i = 0, j = start; i != count; j += step, ++i) {
178  x._Edit(j, 1, value_vector_type(1, values[i]));
179  }
180  }
181  }
182  }
183 
184  static void _DelItemIndex(Type& x, int i)
185  {
186  x._Edit(TfPyNormalizeIndex(i, x._GetSize(), true),
187  1, value_vector_type());
188  }
189 
190  static void _DelItemSlice(Type& x, const pxr_boost::python::slice& index)
191  {
192  using namespace pxr_boost::python;
193 
194  if (x._Validate()) {
195  try {
196  // Get the range and the number of items in the slice.
197  slice::range<typename Type::iterator> range =
198  index.get_indicies(x.begin(), x.end());
199  size_t start = range.start - x.begin();
200  size_t step = range.step;
201  size_t count = 1 + (range.stop - range.start) / range.step;
202 
203  // Erase items.
204  if (step == 1) {
205  x._Edit(start, count, value_vector_type());
206  }
207  else {
208  SdfChangeBlock block;
209  value_vector_type empty;
210  for (size_t j = start; count > 0; j += step - 1, --count) {
211  x._Edit(j, 1, empty);
212  }
213  }
214  }
215  catch (const std::invalid_argument&) {
216  // Empty slice -- do nothing.
217  }
218  }
219  }
220 
221  static int _GetInvalidIndex()
222  {
223  // Note that SdfListProxy::Find returns an unsigned value, however the
224  // wrapped class returns -1 in the event that a value could not be found
225  // in the list of operations.
226  return -1;
227  }
228 
229  static int _FindIndex(const Type& x, const value_type& value)
230  {
231  if (x._Validate()) {
232  const size_t index = x.Find(value);
233  return index == Type::invalidIndex
234  ? _GetInvalidIndex()
235  : static_cast<int>(index);
236  }
237  else {
238  return _GetInvalidIndex();
239  }
240  }
241 
242  static void _Insert(Type& x, int index, const value_type& value)
243  {
244  if (index < 0) {
245  index += x._GetSize();
246  }
247  if (index < 0 || index > static_cast<int>(x._GetSize())) {
248  TfPyThrowIndexError("list index out of range");
249  }
250  x._Edit(index, 0, value_vector_type(1, value));
251  }
252 
253  static bool _IsExpired(const Type& x)
254  {
255  return x.IsExpired();
256  }
257 
258  static value_vector_type _ApplyEditsToList(Type& x,
259  const value_vector_type& values)
260  {
261  value_vector_type newValues = values;
262  x.ApplyEditsToList(&newValues);
263  return newValues;
264  }
265 };
266 
268 
269 #endif // PXR_USD_SDF_PY_LIST_PROXY_H
TF_API std::string TfStringPrintf(const char *fmt,...)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
Type::TypePolicy TypePolicy
Definition: pyListProxy.h:30
GLenum GLint * range
Definition: glcorearb.h:1925
Type::value_vector_type value_vector_type
Definition: pyListProxy.h:32
GLuint start
Definition: glcorearb.h:475
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Type::value_type value_type
Definition: pyListProxy.h:31
TF_API void TfPyThrowValueError(const char *msg)
**But if you need a result
Definition: thread.h:622
uint64 value_type
Definition: GA_PrimCompat.h:29
SdfPyWrapListProxy< Type > This
Definition: pyListProxy.h:33
std::string TfPyRepr(T const &t)
Definition: pyUtils.h:163
TF_API bool TfPyIsNone(pxr_boost::python::object const &obj)
Return true iff obj is None.
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLenum GLint x
Definition: glcorearb.h:409
GLint j
Definition: glad.h:2733
GLsizeiptr size
Definition: glcorearb.h:664
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
if(num_boxed_items<=0)
Definition: UT_RTreeImpl.h:697
TF_API void TfPyThrowIndexError(const char *msg)
OIIO_UTIL_API const char * c_str(string_view str)
TF_API int64_t TfPyNormalizeIndex(int64_t index, uint64_t size, bool throwError=false)
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
GLint GLsizei count
Definition: glcorearb.h:405