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