All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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::GetAddedOrExplicitItems,
159  return_value_policy<TfPySequenceToTuple>())
160  .add_property("isExplicit", &Type::IsExplicit)
161  .add_property("isOrderedOnly", &Type::IsOrderedOnly)
162  .def("ApplyEditsToList",
163  &This::_ApplyEditsToList,
164  return_value_policy<TfPySequenceToList>())
165  .def("ApplyEditsToList",
166  &This::_ApplyEditsToList2,
167  return_value_policy<TfPySequenceToList>())
168 
169  .def("CopyItems", &Type::CopyItems)
170  .def("ClearEdits", &Type::ClearEdits)
171  .def("ClearEditsAndMakeExplicit", &Type::ClearEditsAndMakeExplicit)
172  .def("ContainsItemEdit", &Type::ContainsItemEdit,
173  (arg("item"), arg("onlyAddOrExplicit")=false))
174  .def("RemoveItemEdits", &Type::RemoveItemEdits)
175  .def("ReplaceItemEdits", &Type::ReplaceItemEdits)
176  .def("ModifyItemEdits", &This::_ModifyEdits)
177 
178  // New API (see bug 8710)
179  .def("Add", &Type::Add)
180  .def("Prepend", &Type::Prepend)
181  .def("Append", &Type::Append)
182  .def("Remove", &Type::Remove)
183  .def("Erase", &Type::Erase)
184  ;
185  }
186 
187  static std::string _GetName()
188  {
189  std::string name = "ListEditorProxy_" +
190  ArchGetDemangled<TypePolicy>();
191  name = TfStringReplace(name, " ", "_");
192  name = TfStringReplace(name, ",", "_");
193  name = TfStringReplace(name, "::", "_");
194  name = TfStringReplace(name, "<", "_");
195  name = TfStringReplace(name, ">", "_");
196  return name;
197  }
198 
199  static std::string _GetStr(const Type& x)
200  {
201  return x._listEditor ?
202  boost::lexical_cast<std::string>(*x._listEditor) : std::string();
203  }
204 
205  static void _SetExplicitProxy(Type& x, const value_vector_type& v)
206  {
207  x.GetExplicitItems() = v;
208  }
209 
210  static void _SetAddedProxy(Type& x, const value_vector_type& v)
211  {
212  x.GetAddedItems() = v;
213  }
214 
215  static void _SetPrependedProxy(Type& x, const value_vector_type& v)
216  {
217  x.GetPrependedItems() = v;
218  }
219 
220  static void _SetAppendedProxy(Type& x, const value_vector_type& v)
221  {
222  x.GetAppendedItems() = v;
223  }
224 
225  static void _SetDeletedProxy(Type& x, const value_vector_type& v)
226  {
227  x.GetDeletedItems() = v;
228  }
229 
230  static void _SetOrderedProxy(Type& x, const value_vector_type& v)
231  {
232  x.GetOrderedItems() = v;
233  }
234 
235  static value_vector_type _ApplyEditsToList(const Type& x,
236  const value_vector_type& v)
237  {
238  value_vector_type tmp = v;
239  x.ApplyEditsToList(&tmp);
240  return tmp;
241  }
242 
243  static value_vector_type _ApplyEditsToList2(const Type& x,
244  const value_vector_type& v,
245  const boost::python::object& cb)
246  {
247  value_vector_type tmp = v;
248  x.ApplyEditsToList(&tmp,
249  Sdf_PyListEditorUtils::ApplyHelper<Type, value_type>(x, cb));
250  return tmp;
251  }
252 
253  static void _ModifyEdits(Type& x, const boost::python::object& cb)
254  {
255  x.ModifyItemEdits(Sdf_PyListEditorUtils::ModifyHelper<value_type>(cb));
256  }
257 };
258 
259 PXR_NAMESPACE_CLOSE_SCOPE
260 
261 #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.
Represents a single list of list editing operations.
Definition: listProxy.h:57
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.