Loading...
Searching...
No Matches
pyMapEditProxy.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_MAP_EDIT_PROXY_H
8#define PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/usd/sdf/changeBlock.h"
16#include "pxr/base/tf/pyUtils.h"
18#include "pxr/external/boost/python.hpp"
19
20PXR_NAMESPACE_OPEN_SCOPE
21
22template <class T>
23class SdfPyWrapMapEditProxy {
24public:
25 typedef T Type;
26 typedef typename Type::key_type key_type;
27 typedef typename Type::mapped_type mapped_type;
28 typedef typename Type::value_type value_type;
29 typedef typename Type::iterator iterator;
30 typedef typename Type::const_iterator const_iterator;
31 typedef SdfPyWrapMapEditProxy<Type> This;
32
33 SdfPyWrapMapEditProxy()
34 {
35 TfPyWrapOnce<Type>(&This::_Wrap);
36 }
37
38private:
39 typedef std::pair<key_type, mapped_type> pair_type;
40
41 struct _ExtractItem {
42 static pxr_boost::python::object Get(const const_iterator& i)
43 {
44 return pxr_boost::python::make_tuple(i->first, i->second);
45 }
46 };
47
48 struct _ExtractKey {
49 static pxr_boost::python::object Get(const const_iterator& i)
50 {
51 return pxr_boost::python::object(i->first);
52 }
53 };
54
55 struct _ExtractValue {
56 static pxr_boost::python::object Get(const const_iterator& i)
57 {
58 return pxr_boost::python::object(i->second);
59 }
60 };
61
62 template <class E>
63 class _Iterator {
64 public:
65 _Iterator(const pxr_boost::python::object& object) :
66 _object(object),
67 _owner(pxr_boost::python::extract<const Type&>(object)),
68 _cur(_owner.begin()),
69 _end(_owner.end())
70 {
71 // Do nothing
72 }
73
74 _Iterator<E> GetCopy() const
75 {
76 return *this;
77 }
78
79 pxr_boost::python::object GetNext()
80 {
81 if (_cur == _end) {
82 TfPyThrowStopIteration("End of MapEditProxy iteration");
83 }
84 pxr_boost::python::object result = E::Get(_cur);
85 ++_cur;
86 return result;
87 }
88
89 private:
90 pxr_boost::python::object _object;
91 const Type& _owner;
92 const_iterator _cur;
93 const_iterator _end;
94 };
95
96 static void _Wrap()
97 {
98 using namespace pxr_boost::python;
99
100 std::string name = _GetName();
101
102 scope thisScope =
103 class_<Type>(name.c_str())
104 .def("__repr__", &This::_GetRepr)
105 .def("__str__", &This::_GetStr)
106 .def("__len__", &Type::size)
107 .def("__getitem__", &This::_GetItem)
108 .def("__setitem__", &This::_SetItem)
109 .def("__delitem__", &This::_DelItem)
110 .def("__contains__", &This::_HasKey)
111 .def("__iter__", &This::_GetKeyIterator)
112 .def("values", &This::_GetValueIterator)
113 .def("keys", &This::_GetKeyIterator)
114 .def("items", &This::_GetItemIterator)
115 .def("clear", &Type::clear)
116 .def("get", &This::_PyGet)
117 .def("get", &This::_PyGetDefault)
118 .def("pop", &This::_Pop)
119 .def("popitem", &This::_PopItem)
120 .def("setdefault", &This::_SetDefault)
121 .def("update", &This::_UpdateDict)
122 .def("update", &This::_UpdateList)
123 .def("copy", &This::_Copy)
124 .add_property("expired", &Type::IsExpired)
125 .def("__bool__", &This::_IsValid)
126 .def(self == self)
127 .def(self != self)
128 ;
129
130 class_<_Iterator<_ExtractItem> >
131 ((name + "_Iterator").c_str(), no_init)
132 .def("__iter__", &This::template _Iterator<_ExtractItem>::GetCopy)
133 .def("__next__", &This::template _Iterator<_ExtractItem>::GetNext)
134 ;
135
136 class_<_Iterator<_ExtractKey> >
137 ((name + "_KeyIterator").c_str(), no_init)
138 .def("__iter__", &This::template _Iterator<_ExtractKey>::GetCopy)
139 .def("__next__", &This::template _Iterator<_ExtractKey>::GetNext)
140 ;
141
142 class_<_Iterator<_ExtractValue> >
143 ((name + "_ValueIterator").c_str(), no_init)
144 .def("__iter__", &This::template _Iterator<_ExtractValue>::GetCopy)
145 .def("__next__", &This::template _Iterator<_ExtractValue>::GetNext)
146 ;
147 }
148
149 static std::string _GetName()
150 {
151 std::string name = "MapEditProxy_" +
152 ArchGetDemangled<typename Type::Type>();
153 name = TfStringReplace(name, " ", "_");
154 name = TfStringReplace(name, ",", "_");
155 name = TfStringReplace(name, "::", "_");
156 name = TfStringReplace(name, "<", "_");
157 name = TfStringReplace(name, ">", "_");
158 return name;
159 }
160
161 static std::string _GetRepr(const Type& x)
162 {
163 std::string arg;
164 if (x) {
165 arg = TfStringPrintf("<%s>", x._Location().c_str());
166 }
167 else {
168 arg = "<invalid>";
169 }
170 return TF_PY_REPR_PREFIX + _GetName() + "(" + arg + ")";
171 }
172
173 static std::string _GetStr(const Type& x)
174 {
175 std::string result("{");
176 if (x && ! x.empty()) {
177 const_iterator i = x.begin(), n = x.end();
178 result += TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
179 while (++i != n) {
180 result +=", " + TfPyRepr(i->first) + ": " + TfPyRepr(i->second);
181 }
182 }
183 result += "}";
184 return result;
185 }
186
187 static mapped_type _GetItem(const Type& x, const key_type& key)
188 {
189 const_iterator i = x.find(key);
190 if (i == x.end()) {
192 return mapped_type();
193 }
194 else {
195 return i->second;
196 }
197 }
198
199 static void _SetItem(Type& x, const key_type& key, const mapped_type& value)
200 {
201 std::pair<typename Type::iterator, bool> i =
202 x.insert(value_type(key, value));
203 if (! i.second && i.first != typename Type::iterator()) {
204 i.first->second = value;
205 }
206 }
207
208 static void _DelItem(Type& x, const key_type& key)
209 {
210 x.erase(key);
211 }
212
213 static bool _HasKey(const Type& x, const key_type& key)
214 {
215 return x.count(key) != 0;
216 }
217
218 static _Iterator<_ExtractItem>
219 _GetItemIterator(const pxr_boost::python::object& x)
220 {
221 return _Iterator<_ExtractItem>(x);
222 }
223
224 static _Iterator<_ExtractKey>
225 _GetKeyIterator(const pxr_boost::python::object& x)
226 {
227 return _Iterator<_ExtractKey>(x);
228 }
229
230 static _Iterator<_ExtractValue>
231 _GetValueIterator(const pxr_boost::python::object& x)
232 {
233 return _Iterator<_ExtractValue>(x);
234 }
235
236 static pxr_boost::python::object _PyGet(const Type& x, const key_type& key)
237 {
238 const_iterator i = x.find(key);
239 return i == x.end() ? pxr_boost::python::object() :
240 pxr_boost::python::object(i->second);
241 }
242
243 static mapped_type _PyGetDefault(const Type& x, const key_type& key,
244 const mapped_type& def)
245 {
246 const_iterator i = x.find(key);
247 return i == x.end() ? def : i->second;
248 }
249
250 template <class E>
251 static pxr_boost::python::list _Get(const Type& x)
252 {
253 pxr_boost::python::list result;
254 for (const_iterator i = x.begin(), n = x.end(); i != n; ++i) {
255 result.append(E::Get(i));
256 }
257 return result;
258 }
259
260 static mapped_type _Pop(Type& x, const key_type& key)
261 {
262 iterator i = x.find(key);
263 if (i == x.end()) {
265 return mapped_type();
266 }
267 else {
268 mapped_type result = i->second;
269 x.erase(i);
270 return result;
271 }
272 }
273
274 static pxr_boost::python::tuple _PopItem(Type& x)
275 {
276 if (x.empty()) {
277 TfPyThrowKeyError("MapEditProxy is empty");
278 return pxr_boost::python::tuple();
279 }
280 else {
281 iterator i = x.begin();
282 value_type result = *i;
283 x.erase(i);
284 return pxr_boost::python::make_tuple(result.first, result.second);
285 }
286 }
287
288 static mapped_type _SetDefault(Type& x, const key_type& key,
289 const mapped_type& def)
290 {
291 const_iterator i = x.find(key);
292 if (i != x.end()) {
293 return i->second;
294 }
295 else {
296 return x[key] = def;
297 }
298 }
299
300 static void _Update(Type& x, const std::vector<pair_type>& values)
301 {
302 SdfChangeBlock block;
303 TF_FOR_ALL(i, values) {
304 x[i->first] = i->second;
305 }
306 }
307
308 static void _UpdateDict(Type& x, const pxr_boost::python::dict& d)
309 {
310 _UpdateList(x, d.items());
311 }
312
313 static void _UpdateList(Type& x, const pxr_boost::python::list& pairs)
314 {
315 using namespace pxr_boost::python;
316
317 std::vector<pair_type> values;
318 for (int i = 0, n = len(pairs); i != n; ++i) {
319 values.push_back(pair_type(
320 extract<key_type>(pairs[i][0])(),
321 extract<mapped_type>(pairs[i][1])()));
322 }
323 _Update(x, values);
324 }
325
326 static void _Copy(Type& x, const typename Type::Type& other)
327 {
328 x = other;
329 }
330
331 static bool _IsValid(const Type& x)
332 {
333 return static_cast<bool>(x);
334 }
335};
336
337PXR_NAMESPACE_CLOSE_SCOPE
338
339#endif // PXR_USD_SDF_PY_MAP_EDIT_PROXY_H
A simple iterator adapter for STL containers.
Miscellaneous Utilities for dealing with script.
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 void TfPyThrowKeyError(const char *msg)
Raises a Python KeyError with the given error msg and throws a pxr_boost::python::error_already_set e...
#define TF_PY_REPR_PREFIX
A macro which expands to the proper repr prefix for a library.
Definition: pyUtils.h:42
std::string TfPyRepr(T const &t)
Return repr(t).
Definition: pyUtils.h:163
DANGER DANGER DANGER
Definition: changeBlock.h:56
Demangle C++ typenames generated by the typeid() facility.
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
Definition: iterator.h:373
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.
TF_API std::string TfStringPrintf(const char *fmt,...)
Returns a string formed by a printf()-like specification.
Definitions of basic string utilities in tf.