pyListEditorProxy.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_EDITOR_PROXY_H
25 #define PXR_USD_SDF_PY_LIST_EDITOR_PROXY_H
26 
28 
29 #include "pxr/pxr.h"
31 #include "pxr/usd/sdf/listOp.h"
33 
34 #include "pxr/base/arch/demangle.h"
35 #include "pxr/base/tf/diagnostic.h"
36 #include "pxr/base/tf/pyCall.h"
37 #include "pxr/base/tf/pyResultConversions.h"
38 #include "pxr/base/tf/pyLock.h"
39 #include "pxr/base/tf/pyUtils.h"
41 #include <boost/python.hpp>
42 
43 PXR_NAMESPACE_OPEN_SCOPE
44 
45 class Sdf_PyListEditorUtils {
46 public:
47  template <class T, class V>
48  class ApplyHelper {
49  public:
50  ApplyHelper(const T& owner, const boost::python::object& callback) :
51  _owner(owner),
52  _callback(callback)
53  {
54  // Do nothing
55  }
56 
57  boost::optional<V> operator()(SdfListOpType op, const V& value)
58  {
59  using namespace boost::python;
60 
61  TfPyLock pyLock;
62  object result = _callback(_owner, value, op);
63  if (! TfPyIsNone(result)) {
64  extract<V> e(result);
65  if (e.check()) {
66  return boost::optional<V>(e());
67  }
68  else {
69  TF_CODING_ERROR("ApplyEditsToList callback has "
70  "incorrect return type.");
71  }
72  }
73  return boost::optional<V>();
74  }
75 
76  private:
77  const T& _owner;
79  };
80 
81  template <class V>
82  class ModifyHelper {
83  public:
84  ModifyHelper(const boost::python::object& callback) :
85  _callback(callback)
86  {
87  // Do nothing
88  }
89 
90  boost::optional<V> operator()(const V& value)
91  {
92  using namespace boost::python;
93 
94  TfPyLock pyLock;
95  object result = _callback(value);
96  if (! TfPyIsNone(result)) {
97  extract<V> e(result);
98  if (e.check()) {
99  return boost::optional<V>(e());
100  }
101  else {
102  TF_CODING_ERROR("ModifyItemEdits callback has "
103  "incorrect return type.");
104  }
105  }
106  return boost::optional<V>();
107  }
108 
109  private:
111  };
112 };
113 
114 template <class T>
115 class SdfPyWrapListEditorProxy {
116 public:
117  typedef T Type;
118  typedef typename Type::TypePolicy TypePolicy;
119  typedef typename Type::value_type value_type;
120  typedef typename Type::value_vector_type value_vector_type;
121  typedef typename Type::ApplyCallback ApplyCallback;
122  typedef typename Type::ModifyCallback ModifyCallback;
123  typedef SdfPyWrapListEditorProxy<Type> This;
124  typedef SdfListProxy<TypePolicy> ListProxy;
125 
126  SdfPyWrapListEditorProxy()
127  {
128  TfPyWrapOnce<Type>(&This::_Wrap);
129  SdfPyWrapListProxy<ListProxy>();
130  }
131 
132 private:
133  static void _Wrap()
134  {
135  using namespace boost::python;
136 
137  class_<Type>(_GetName().c_str(), no_init)
138  .def("__str__", &This::_GetStr)
139  .add_property("isExpired", &Type::IsExpired)
140  .add_property("explicitItems",
141  &Type::GetExplicitItems,
142  &This::_SetExplicitProxy)
143  .add_property("addedItems",
144  &Type::GetAddedItems,
145  &This::_SetAddedProxy)
146  .add_property("prependedItems",
147  &Type::GetPrependedItems,
148  &This::_SetPrependedProxy)
149  .add_property("appendedItems",
150  &Type::GetAppendedItems,
151  &This::_SetAppendedProxy)
152  .add_property("deletedItems",
153  &Type::GetDeletedItems,
154  &This::_SetDeletedProxy)
155  .add_property("orderedItems",
156  &Type::GetOrderedItems,
157  &This::_SetOrderedProxy)
158  .def("GetAddedOrExplicitItems", &Type::GetAppliedItems,
159  return_value_policy<TfPySequenceToTuple>()) // deprecated
160  .def("GetAppliedItems", &Type::GetAppliedItems,
161  return_value_policy<TfPySequenceToTuple>())
162  .add_property("isExplicit", &Type::IsExplicit)
163  .add_property("isOrderedOnly", &Type::IsOrderedOnly)
164  .def("ApplyEditsToList",
165  &This::_ApplyEditsToList,
166  return_value_policy<TfPySequenceToList>())
167  .def("ApplyEditsToList",
168  &This::_ApplyEditsToList2,
169  return_value_policy<TfPySequenceToList>())
170 
171  .def("CopyItems", &Type::CopyItems)
172  .def("ClearEdits", &Type::ClearEdits)
173  .def("ClearEditsAndMakeExplicit", &Type::ClearEditsAndMakeExplicit)
174  .def("ContainsItemEdit", &Type::ContainsItemEdit,
175  (arg("item"), arg("onlyAddOrExplicit")=false))
176  .def("RemoveItemEdits", &Type::RemoveItemEdits)
177  .def("ReplaceItemEdits", &Type::ReplaceItemEdits)
178  .def("ModifyItemEdits", &This::_ModifyEdits)
179 
180  // New API (see bug 8710)
181  .def("Add", &Type::Add)
182  .def("Prepend", &Type::Prepend)
183  .def("Append", &Type::Append)
184  .def("Remove", &Type::Remove)
185  .def("Erase", &Type::Erase)
186  ;
187  }
188 
189  static std::string _GetName()
190  {
191  std::string name = "ListEditorProxy_" +
192  ArchGetDemangled<TypePolicy>();
193  name = TfStringReplace(name, " ", "_");
194  name = TfStringReplace(name, ",", "_");
195  name = TfStringReplace(name, "::", "_");
196  name = TfStringReplace(name, "<", "_");
197  name = TfStringReplace(name, ">", "_");
198  return name;
199  }
200 
201  static std::string _GetStr(const Type& x)
202  {
203  return x._listEditor ?
204  boost::lexical_cast<std::string>(*x._listEditor) : std::string();
205  }
206 
207  static void _SetExplicitProxy(Type& x, const value_vector_type& v)
208  {
209  x.GetExplicitItems() = v;
210  }
211 
212  static void _SetAddedProxy(Type& x, const value_vector_type& v)
213  {
214  x.GetAddedItems() = v;
215  }
216 
217  static void _SetPrependedProxy(Type& x, const value_vector_type& v)
218  {
219  x.GetPrependedItems() = v;
220  }
221 
222  static void _SetAppendedProxy(Type& x, const value_vector_type& v)
223  {
224  x.GetAppendedItems() = v;
225  }
226 
227  static void _SetDeletedProxy(Type& x, const value_vector_type& v)
228  {
229  x.GetDeletedItems() = v;
230  }
231 
232  static void _SetOrderedProxy(Type& x, const value_vector_type& v)
233  {
234  x.GetOrderedItems() = v;
235  }
236 
237  static value_vector_type _ApplyEditsToList(const Type& x,
238  const value_vector_type& v)
239  {
240  value_vector_type tmp = v;
241  x.ApplyEditsToList(&tmp);
242  return tmp;
243  }
244 
245  static value_vector_type _ApplyEditsToList2(const Type& x,
246  const value_vector_type& v,
247  const boost::python::object& cb)
248  {
249  value_vector_type tmp = v;
250  x.ApplyEditsToList(&tmp,
251  Sdf_PyListEditorUtils::ApplyHelper<Type, value_type>(x, cb));
252  return tmp;
253  }
254 
255  static void _ModifyEdits(Type& x, const boost::python::object& cb)
256  {
257  x.ModifyItemEdits(Sdf_PyListEditorUtils::ModifyHelper<value_type>(cb));
258  }
259 };
260 
261 PXR_NAMESPACE_CLOSE_SCOPE
262 
263 #endif // PXR_USD_SDF_PY_LIST_EDITOR_PROXY_H
Utilities for calling python callables.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
Definitions of basic string utilities in tf.
Low-level utilities for informing users of various internal and external diagnostic conditions.
Miscellaneous Utilities for dealing with script.
Demangle C++ typenames generated by the typeid() facility.
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:122
Represents a single list of list editing operations.
Definition: listProxy.h:59
Provide a way to call a Python callable.
Definition: pyCall.h:57
TF_API bool TfPyIsNone(boost::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)
Replaces all occurrences of string from with to in source.