Loading...
Searching...
No Matches
pyChildrenProxy.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_CHILDREN_PROXY_H
8#define PXR_USD_SDF_PY_CHILDREN_PROXY_H
9
11
12#include "pxr/pxr.h"
15#include "pxr/base/tf/pyError.h"
16#include "pxr/base/tf/pyUtils.h"
18#include "pxr/external/boost/python.hpp"
19#include "pxr/external/boost/python/slice.hpp"
20
21PXR_NAMESPACE_OPEN_SCOPE
22
23template <class _View>
24class SdfPyChildrenProxy {
25public:
26 typedef _View View;
27 typedef SdfChildrenProxy<View> Proxy;
28 typedef typename Proxy::key_type key_type;
29 typedef typename Proxy::mapped_type mapped_type;
30 typedef typename Proxy::mapped_vector_type mapped_vector_type;
31 typedef typename Proxy::size_type size_type;
32 typedef SdfPyChildrenProxy<View> This;
33
34 SdfPyChildrenProxy(const Proxy& proxy) : _proxy(proxy)
35 {
36 _Init();
37 }
38
39 SdfPyChildrenProxy(const View& view, const std::string& type,
40 int permission = Proxy::CanSet |
41 Proxy::CanInsert |
42 Proxy::CanErase) :
43 _proxy(view, type, permission)
44 {
45 _Init();
46 }
47
48 bool operator==(const This& other) const
49 {
50 return _proxy == other._proxy;
51 }
52
53 bool operator!=(const This& other) const
54 {
55 return _proxy != other._proxy;
56 }
57
58private:
59 typedef typename Proxy::const_iterator _const_iterator;
60 typedef typename View::const_iterator _view_const_iterator;
61
62 struct _ExtractItem {
63 static pxr_boost::python::object Get(const _const_iterator& i)
64 {
65 return pxr_boost::python::make_tuple(i->first, i->second);
66 }
67 };
68
69 struct _ExtractKey {
70 static pxr_boost::python::object Get(const _const_iterator& i)
71 {
72 return pxr_boost::python::object(i->first);
73 }
74 };
75
76 struct _ExtractValue {
77 static pxr_boost::python::object Get(const _const_iterator& i)
78 {
79 return pxr_boost::python::object(i->second);
80 }
81 };
82
83 template <class E>
84 class _Iterator {
85 public:
86 _Iterator(const pxr_boost::python::object& object) :
87 _object(object),
88 _owner(pxr_boost::python::extract<const This&>(object)()._proxy)
89 {
90 _cur = _owner.begin();
91 }
92
93 _Iterator<E> GetCopy() const
94 {
95 return *this;
96 }
97
98 pxr_boost::python::object GetNext()
99 {
100 if (_cur == _owner.end()) {
101 TfPyThrowStopIteration("End of ChildrenProxy iteration");
102 }
103 pxr_boost::python::object result = E::Get(_cur);
104 ++_cur;
105 return result;
106 }
107
108 private:
109 pxr_boost::python::object _object;
110 const Proxy& _owner;
111 _const_iterator _cur;
112 };
113
114 void _Init()
115 {
116 TfPyWrapOnce<This>(&This::_Wrap);
117 }
118
119 static void _Wrap()
120 {
121 using namespace pxr_boost::python;
122
123 std::string name = _GetName();
124
125 scope thisScope =
126 class_<This>(name.c_str(), no_init)
127 .def("__repr__", &This::_GetRepr, TfPyRaiseOnError<>())
128 .def("__len__", &This::_GetSize, TfPyRaiseOnError<>())
129 .def("__getitem__", &This::_GetItemByKey, TfPyRaiseOnError<>())
130 .def("__getitem__", &This::_GetItemByIndex, TfPyRaiseOnError<>())
131 .def("__setitem__", &This::_SetItemByKey, TfPyRaiseOnError<>())
132 .def("__setitem__", &This::_SetItemBySlice, TfPyRaiseOnError<>())
133 .def("__delitem__", &This::_DelItemByKey, TfPyRaiseOnError<>())
134 .def("__delitem__", &This::_DelItemByIndex, TfPyRaiseOnError<>())
135 .def("__contains__", &This::_HasKey, TfPyRaiseOnError<>())
136 .def("__contains__", &This::_HasValue, TfPyRaiseOnError<>())
137 .def("__iter__", &This::_GetValueIterator, TfPyRaiseOnError<>())
138 .def("clear", &This::_Clear, TfPyRaiseOnError<>())
139 .def("append", &This::_AppendItem, TfPyRaiseOnError<>())
140 .def("insert", &This::_InsertItemByIndex, TfPyRaiseOnError<>())
141 .def("get", &This::_PyGet, TfPyRaiseOnError<>())
142 .def("get", &This::_PyGetDefault, TfPyRaiseOnError<>())
143 .def("items", &This::_GetItemIterator, TfPyRaiseOnError<>())
144 .def("keys", &This::_GetKeyIterator, TfPyRaiseOnError<>())
145 .def("values", &This::_GetValueIterator, TfPyRaiseOnError<>())
146 .def("index", &This::_FindIndexByKey, TfPyRaiseOnError<>())
147 .def("index", &This::_FindIndexByValue, TfPyRaiseOnError<>())
148 .def("__eq__", &This::operator==, TfPyRaiseOnError<>())
149 .def("__ne__", &This::operator!=, TfPyRaiseOnError<>())
150 ;
151
152 class_<_Iterator<_ExtractItem> >
153 ((name + "_Iterator").c_str(), no_init)
154 .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
155 .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
156 ;
157
158 class_<_Iterator<_ExtractKey> >
159 ((name + "_KeyIterator").c_str(), no_init)
160 .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
161 .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
162 ;
163
164 class_<_Iterator<_ExtractValue> >
165 ((name + "_ValueIterator").c_str(), no_init)
166 .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
167 .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
168 ;
169 }
170
171 static std::string _GetName()
172 {
173 std::string name = "ChildrenProxy_" +
174 ArchGetDemangled<View>();
175 name = TfStringReplace(name, " ", "_");
176 name = TfStringReplace(name, ",", "_");
177 name = TfStringReplace(name, "::", "_");
178 name = TfStringReplace(name, "<", "_");
179 name = TfStringReplace(name, ">", "_");
180 return name;
181 }
182
183 const View& _GetView() const
184 {
185 return _proxy._view;
186 }
187
188 View& _GetView()
189 {
190 return _proxy._view;
191 }
192
193 std::string _GetRepr() const
194 {
195 std::string result("{");
196 if (! _proxy.empty()) {
197 _const_iterator i = _proxy.begin(), n = _proxy.end();
198 result += TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
199 while (++i != n) {
200 result += ", " + TfPyRepr(i->first) +
201 ": " + TfPyRepr(i->second);
202 }
203 }
204 result += "}";
205 return result;
206 }
207
208 size_type _GetSize() const
209 {
210 return _proxy.size();
211 }
212
213 mapped_type _GetItemByKey(const key_type& key) const
214 {
215 _view_const_iterator i = _GetView().find(key);
216 if (i == _GetView().end()) {
218 return mapped_type();
219 }
220 else {
221 return *i;
222 }
223 }
224
225 mapped_type _GetItemByIndex(int index) const
226 {
227 index = TfPyNormalizeIndex(index, _proxy.size(), true /*throwError*/);
228 return _GetView()[index];
229 }
230
231 void _SetItemByKey(const key_type& key, const mapped_type& value)
232 {
233 TF_CODING_ERROR("can't directly reparent a %s",
234 _proxy._GetType().c_str());
235 }
236
237 void _SetItemBySlice(const pxr_boost::python::slice& slice,
238 const mapped_vector_type& values)
239 {
240 if (! TfPyIsNone(slice.start()) ||
241 ! TfPyIsNone(slice.stop()) ||
242 ! TfPyIsNone(slice.step())) {
243 TfPyThrowIndexError("can only assign to full slice [:]");
244 }
245 else {
246 _proxy._Copy(values);
247 }
248 }
249
250 void _DelItemByKey(const key_type& key)
251 {
252 if (_GetView().find(key) == _GetView().end()) {
254 }
255 _proxy._Erase(key);
256 }
257
258 void _DelItemByIndex(int index)
259 {
260 _proxy._Erase(_GetView().key(_GetItemByIndex(index)));
261 }
262
263 void _Clear()
264 {
265 _proxy._Copy(mapped_vector_type());
266 }
267
268 void _AppendItem(const mapped_type& value)
269 {
270 _proxy._Insert(value, _proxy.size());
271 }
272
273 void _InsertItemByIndex(int index, const mapped_type& value)
274 {
275 // Note that -1 below means to insert at end for the _proxy._Insert API.
276 index = index < (int)_proxy.size()
277 ? TfPyNormalizeIndex(index, _proxy.size(), false /*throwError*/)
278 : -1;
279
280 _proxy._Insert(value, index);
281 }
282
283 pxr_boost::python::object _PyGet(const key_type& key) const
284 {
285 _view_const_iterator i = _GetView().find(key);
286 return i == _GetView().end() ? pxr_boost::python::object() :
287 pxr_boost::python::object(*i);
288 }
289
290 pxr_boost::python::object _PyGetDefault(const key_type& key,
291 const mapped_type& def) const
292 {
293 _view_const_iterator i = _GetView().find(key);
294 return i == _GetView().end() ? pxr_boost::python::object(def) :
295 pxr_boost::python::object(*i);
296 }
297
298 bool _HasKey(const key_type& key) const
299 {
300 return _GetView().find(key) != _GetView().end();
301 }
302
303 bool _HasValue(const mapped_type& value) const
304 {
305 return _GetView().find(value) != _GetView().end();
306 }
307
308 static
309 _Iterator<_ExtractItem> _GetItemIterator(const pxr_boost::python::object &x)
310 {
311 return _Iterator<_ExtractItem>(x);
312 }
313
314 static
315 _Iterator<_ExtractKey> _GetKeyIterator(const pxr_boost::python::object &x)
316 {
317 return _Iterator<_ExtractKey>(x);
318 }
319
320 static
321 _Iterator<_ExtractValue> _GetValueIterator(const pxr_boost::python::object &x)
322 {
323 return _Iterator<_ExtractValue>(x);
324 }
325
326 template <class E>
327 pxr_boost::python::list _Get() const
328 {
329 pxr_boost::python::list result;
330 for (_const_iterator i = _proxy.begin(), n = _proxy.end(); i != n; ++i){
331 result.append(E::Get(i));
332 }
333 return result;
334 }
335
336 int _FindIndexByKey(const key_type& key) const
337 {
338 size_t i = std::distance(_GetView().begin(), _GetView().find(key));
339 return i == _GetView().size() ? -1 : i;
340 }
341
342 int _FindIndexByValue(const mapped_type& value) const
343 {
344 size_t i = std::distance(_GetView().begin(), _GetView().find(value));
345 return i == _GetView().size() ? -1 : i;
346 }
347
348private:
349 Proxy _proxy;
350
351 template <class E> friend class _Iterator;
352};
353
354PXR_NAMESPACE_CLOSE_SCOPE
355
356#endif // PXR_USD_SDF_PY_CHILDREN_PROXY_H
Miscellaneous Utilities for dealing with script.
TF_API void TfPyThrowIndexError(const char *msg)
Raises a Python IndexError with the given error msg and throws a pxr_boost::python::error_already_set...
TF_API void TfPyThrowStopIteration(const char *msg)
Raises a Python StopIteration with the given error msg and throws a pxr_boost::python::error_already_...
TF_API bool TfPyIsNone(pxr_boost::python::object const &obj)
Return true iff obj is None.
TF_API int64_t TfPyNormalizeIndex(int64_t index, uint64_t size, bool throwError=false)
Return a positive index in the range [0,size).
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:163
Demangle C++ typenames generated by the typeid() facility.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:68
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
Replaces all occurrences of string from with to in source.
Definitions of basic string utilities in tf.
A boost.python call policy class which, when applied to a wrapped function, will create an error mark...
Definition: pyError.h:47