All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
listEditorProxy.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 SDF_LISTEDITORPROXY_H
25 #define SDF_LISTEDITORPROXY_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/listEditor.h"
31 #include "pxr/usd/sdf/listProxy.h"
32 #include "pxr/usd/sdf/changeBlock.h"
33 
34 #include "pxr/base/vt/value.h" // for Vt_DefaultValueFactory
35 
36 #include <boost/optional.hpp>
37 #include <boost/shared_ptr.hpp>
38 
39 #include <functional>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
56 template <class _TypePolicy>
58 public:
59  typedef _TypePolicy TypePolicy;
62  typedef typename TypePolicy::value_type value_type;
63  typedef std::vector<value_type> value_vector_type;
64 
65  // ApplyEdits types.
66  typedef std::function<boost::optional<value_type>
67  (SdfListOpType, const value_type&)> ApplyCallback;
68 
69  // ModifyEdits types.
70  typedef std::function<boost::optional<value_type>
71  (const value_type&)> ModifyCallback;
72 
76  {
77  }
78 
81  const boost::shared_ptr<Sdf_ListEditor<TypePolicy> >& listEditor)
82  : _listEditor(listEditor)
83  {
84  }
85 
87  bool IsExpired() const
88  {
89  if (!_listEditor) {
90  return false;
91  }
92 
93  return _listEditor->IsExpired();
94  }
95 
98  bool IsExplicit() const
99  {
100  return _Validate() ? _listEditor->IsExplicit() : true;
101  }
102 
105  bool IsOrderedOnly() const
106  {
107  return _Validate() ? _listEditor->IsOrderedOnly() : false;
108  }
109 
113  bool HasKeys() const
114  {
115  return _Validate() ? _listEditor->HasKeys() : true;
116  }
117 
119  void ApplyEditsToList(value_vector_type* vec) const
120  {
121  if (_Validate()) {
122  _listEditor->ApplyEditsToList(vec, ApplyCallback());
123  }
124  }
125 
131  template <class CB>
132  void ApplyEditsToList(value_vector_type* vec, CB callback) const
133  {
134  if (_Validate()) {
135  _listEditor->ApplyEditsToList(vec, ApplyCallback(callback));
136  }
137  }
138 
146  bool CopyItems(const This& other)
147  {
148  return _Validate() && other._Validate() ?
149  _listEditor->CopyEdits(*other._listEditor) : false;
150  }
151 
157  bool ClearEdits()
158  {
159  return _Validate() ? _listEditor->ClearEdits() : false;
160  }
161 
168  {
169  return _Validate() ? _listEditor->ClearEditsAndMakeExplicit() : false;
170  }
171 
175  template <class CB>
176  void ModifyItemEdits(CB callback)
177  {
178  if (_Validate()) {
179  _listEditor->ModifyItemEdits(ModifyCallback(callback));
180  }
181  }
182 
186  bool ContainsItemEdit(const value_type& item,
187  bool onlyAddOrExplicit = false) const
188  {
189  if (_Validate()) {
190  size_t i;
191 
192  i = GetExplicitItems().Find(item);
193  if (i != size_t(-1)) {
194  return true;
195  }
196 
197  i = GetAddedItems().Find(item);
198  if (i != size_t(-1)) {
199  return true;
200  }
201 
202  i = GetPrependedItems().Find(item);
203  if (i != size_t(-1)) {
204  return true;
205  }
206 
207  i = GetAppendedItems().Find(item);
208  if (i != size_t(-1)) {
209  return true;
210  }
211 
212  if (!onlyAddOrExplicit) {
213  i = GetDeletedItems().Find(item);
214  if (i != size_t(-1)) {
215  return true;
216  }
217 
218  i = GetOrderedItems().Find(item);
219  if (i != size_t(-1)) {
220  return true;
221  }
222  }
223  }
224 
225  return false;
226  }
227 
230  void RemoveItemEdits(const value_type& item)
231  {
232  if (_Validate()) {
233  SdfChangeBlock block;
234 
235  GetExplicitItems().Remove(item);
236  GetAddedItems().Remove(item);
237  GetPrependedItems().Remove(item);
238  GetAppendedItems().Remove(item);
239  GetDeletedItems().Remove(item);
240  GetOrderedItems().Remove(item);
241  }
242  }
243 
247  void ReplaceItemEdits(const value_type& oldItem, const value_type& newItem)
248  {
249  if (_Validate()) {
250  SdfChangeBlock block;
251 
252  GetExplicitItems().Replace(oldItem, newItem);
253  GetAddedItems().Replace(oldItem, newItem);
254  GetPrependedItems().Replace(oldItem, newItem);
255  GetAppendedItems().Replace(oldItem, newItem);
256  GetDeletedItems().Replace(oldItem, newItem);
257  GetOrderedItems().Replace(oldItem, newItem);
258  }
259  }
260 
263  {
264  return ListProxy(_listEditor, SdfListOpTypeExplicit);
265  }
266 
269  {
270  return ListProxy(_listEditor, SdfListOpTypeAdded);
271  }
272 
275  {
276  return ListProxy(_listEditor, SdfListOpTypePrepended);
277  }
278 
281  {
282  return ListProxy(_listEditor, SdfListOpTypeAppended);
283  }
284 
287  {
288  return ListProxy(_listEditor, SdfListOpTypeDeleted);
289  }
290 
293  {
294  return ListProxy(_listEditor, SdfListOpTypeOrdered);
295  }
296 
298  value_vector_type GetAddedOrExplicitItems() const
299  {
300  value_vector_type result;
301  if (_Validate()) {
302  _listEditor->ApplyEditsToList(&result);
303  }
304  return result;
305  }
306 
307  void Add(const value_type& value)
308  {
309  if (_Validate()) {
310  if (!_listEditor->IsOrderedOnly()) {
311  if (_listEditor->IsExplicit()) {
312  _AddOrReplace(SdfListOpTypeExplicit, value);
313  }
314  else {
315  GetDeletedItems().Remove(value);
316  _AddOrReplace(SdfListOpTypeAdded, value);
317  }
318  }
319  }
320  }
321 
322  void Prepend(const value_type& value)
323  {
324  if (_Validate()) {
325  if (!_listEditor->IsOrderedOnly()) {
326  if (_listEditor->IsExplicit()) {
327  _Prepend(SdfListOpTypeExplicit, value);
328  }
329  else {
330  GetDeletedItems().Remove(value);
331  _Prepend(SdfListOpTypePrepended, value);
332  }
333  }
334  }
335  }
336 
337  void Append(const value_type& value)
338  {
339  if (_Validate()) {
340  if (!_listEditor->IsOrderedOnly()) {
341  if (_listEditor->IsExplicit()) {
342  _Append(SdfListOpTypeExplicit, value);
343  }
344  else {
345  GetDeletedItems().Remove(value);
346  _Append(SdfListOpTypeAppended, value);
347  }
348  }
349  }
350  }
351 
352  void Remove(const value_type& value)
353  {
354  if (_Validate()) {
355  if (_listEditor->IsExplicit()) {
356  GetExplicitItems().Remove(value);
357  }
358  else if (!_listEditor->IsOrderedOnly()) {
359  GetAddedItems().Remove(value);
360  GetPrependedItems().Remove(value);
361  GetAppendedItems().Remove(value);
362  _AddIfMissing(SdfListOpTypeDeleted, value);
363  }
364  }
365  }
366 
367  void Erase(const value_type& value)
368  {
369  if (_Validate()) {
370  if (!_listEditor->IsOrderedOnly()) {
371  if (_listEditor->IsExplicit()) {
372  GetExplicitItems().Remove(value);
373  }
374  else {
375  GetAddedItems().Remove(value);
376  GetPrependedItems().Remove(value);
377  GetAppendedItems().Remove(value);
378  }
379  }
380  }
381  }
382 
386  explicit operator bool() const
387  {
388  return _listEditor && _listEditor->IsValid();
389  }
390 
391 private:
392  bool _Validate()
393  {
394  if (!_listEditor) {
395  return false;
396  }
397 
398  if (IsExpired()) {
399  TF_CODING_ERROR("Accessing expired list editor");
400  return false;
401  }
402  return true;
403  }
404 
405  bool _Validate() const
406  {
407  if (!_listEditor) {
408  return false;
409  }
410 
411  if (IsExpired()) {
412  TF_CODING_ERROR("Accessing expired list editor");
413  return false;
414  }
415  return true;
416  }
417 
418  void _AddIfMissing(SdfListOpType op, const value_type& value)
419  {
420  ListProxy proxy(_listEditor, op);
421  size_t index = proxy.Find(value);
422  if (index == size_t(-1)) {
423  proxy.push_back(value);
424  }
425  }
426 
427  void _AddOrReplace(SdfListOpType op, const value_type& value)
428  {
429  ListProxy proxy(_listEditor, op);
430  size_t index = proxy.Find(value);
431  if (index == size_t(-1)) {
432  proxy.push_back(value);
433  }
434  else if (value != static_cast<value_type>(proxy[index])) {
435  proxy[index] = value;
436  }
437  }
438 
439  void _Prepend(SdfListOpType op, const value_type& value)
440  {
441  ListProxy proxy(_listEditor, op);
442  size_t index = proxy.Find(value);
443  if (index != 0) {
444  if (index != size_t(-1)) {
445  proxy.Erase(index);
446  }
447  proxy.insert(proxy.begin(), value);
448  }
449  }
450 
451  void _Append(SdfListOpType op, const value_type& value)
452  {
453  ListProxy proxy(_listEditor, op);
454  size_t index = proxy.Find(value);
455  if (proxy.empty() || (index != proxy.size()-1)) {
456  if (index != size_t(-1)) {
457  proxy.Erase(index);
458  }
459  proxy.push_back(value);
460  }
461  }
462 
463 private:
464  boost::shared_ptr<Sdf_ListEditor<TypePolicy> > _listEditor;
465 
466  friend class Sdf_ListEditorProxyAccess;
467  template <class T> friend class SdfPyWrapListEditorProxy;
468 };
469 
470 // Cannot get from a VtValue except as the correct type.
471 template <class TP>
472 struct Vt_DefaultValueFactory<SdfListEditorProxy<TP> > {
473  static Vt_DefaultValueHolder Invoke() = delete;
474 };
475 
476 PXR_NAMESPACE_CLOSE_SCOPE
477 
478 #endif // SDF_LISTEDITORPROXY_H
void RemoveItemEdits(const value_type &item)
Remove all occurrences of the given item, regardless of whether the item is explicit, added, prepended, appended, deleted, or ordered.
ListProxy GetDeletedItems() const
Returns the items deleted by this list editor.
bool ClearEdits()
Removes all keys and changes the editor to have list operations.
ListProxy GetOrderedItems() const
Returns the items reordered by this list editor.
void ApplyEditsToList(value_vector_type *vec, CB callback) const
Apply the edits to vec.
ListProxy GetAppendedItems() const
Returns the items appended by this list editor.
Represents a set of list editing operations.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
bool IsExplicit() const
Returns true if the editor has an explicit list, false if it has list operations. ...
bool HasKeys() const
Returns true if the editor has an explicit list (even if it&#39;s empty) or it has any added...
void ApplyEditsToList(value_vector_type *vec) const
Apply the edits to vec.
DANGER DANGER DANGER
Definition: changeBlock.h:72
Represents a single list of list editing operations.
Definition: listProxy.h:57
void ReplaceItemEdits(const value_type &oldItem, const value_type &newItem)
Replace all occurrences of the given item, regardless of whether the item is explicit, added, prepended, appended, deleted or ordered.
ListProxy GetAddedItems() const
Returns the items added by this list editor.
bool ContainsItemEdit(const value_type &item, bool onlyAddOrExplicit=false) const
Check if the given item is explicit, added, prepended, appended, deleted, or ordered by this editor...
bool CopyItems(const This &other)
Copies the keys from other.
bool ClearEditsAndMakeExplicit()
Removes all keys and changes the editor to be explicit.
ListProxy GetPrependedItems() const
Returns the items prepended by this list editor.
value_vector_type GetAddedOrExplicitItems() const
Returns the added or explicitly set items.
void ModifyItemEdits(CB callback)
callback is called for every key.
ListProxy GetExplicitItems() const
Returns the explicitly set items.
SdfListEditorProxy()
Creates a default proxy object.
SdfListEditorProxy(const boost::shared_ptr< Sdf_ListEditor< TypePolicy > > &listEditor)
Creates a new proxy object backed by the supplied list editor.
bool IsOrderedOnly() const
Returns true if the editor is not explicit and allows ordering only.
bool IsExpired() const
Returns true if the list editor is expired.