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 PXR_USD_SDF_LIST_EDITOR_PROXY_H
25 #define PXR_USD_SDF_LIST_EDITOR_PROXY_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 
38 #include <functional>
39 #include <memory>
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 std::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  return GetAppliedItems();
301  }
302 
309 
310  value_vector_type GetAppliedItems() const
311  {
312  value_vector_type result;
313  if (_Validate()) {
314  _listEditor->ApplyEditsToList(&result);
315  }
316  return result;
317  }
318 
319  void Add(const value_type& value)
320  {
321  if (_Validate()) {
322  if (!_listEditor->IsOrderedOnly()) {
323  if (_listEditor->IsExplicit()) {
324  _AddOrReplace(SdfListOpTypeExplicit, value);
325  }
326  else {
327  GetDeletedItems().Remove(value);
328  _AddOrReplace(SdfListOpTypeAdded, value);
329  }
330  }
331  }
332  }
333 
334  void Prepend(const value_type& value)
335  {
336  if (_Validate()) {
337  if (!_listEditor->IsOrderedOnly()) {
338  if (_listEditor->IsExplicit()) {
339  _Prepend(SdfListOpTypeExplicit, value);
340  }
341  else {
342  GetDeletedItems().Remove(value);
343  _Prepend(SdfListOpTypePrepended, value);
344  }
345  }
346  }
347  }
348 
349  void Append(const value_type& value)
350  {
351  if (_Validate()) {
352  if (!_listEditor->IsOrderedOnly()) {
353  if (_listEditor->IsExplicit()) {
354  _Append(SdfListOpTypeExplicit, value);
355  }
356  else {
357  GetDeletedItems().Remove(value);
358  _Append(SdfListOpTypeAppended, value);
359  }
360  }
361  }
362  }
363 
364  void Remove(const value_type& value)
365  {
366  if (_Validate()) {
367  if (_listEditor->IsExplicit()) {
368  GetExplicitItems().Remove(value);
369  }
370  else if (!_listEditor->IsOrderedOnly()) {
371  GetAddedItems().Remove(value);
372  GetPrependedItems().Remove(value);
373  GetAppendedItems().Remove(value);
374  _AddIfMissing(SdfListOpTypeDeleted, value);
375  }
376  }
377  }
378 
379  void Erase(const value_type& value)
380  {
381  if (_Validate()) {
382  if (!_listEditor->IsOrderedOnly()) {
383  if (_listEditor->IsExplicit()) {
384  GetExplicitItems().Remove(value);
385  }
386  else {
387  GetAddedItems().Remove(value);
388  GetPrependedItems().Remove(value);
389  GetAppendedItems().Remove(value);
390  }
391  }
392  }
393  }
394 
398  explicit operator bool() const
399  {
400  return _listEditor && _listEditor->IsValid();
401  }
402 
403 private:
404  bool _Validate()
405  {
406  if (!_listEditor) {
407  return false;
408  }
409 
410  if (IsExpired()) {
411  TF_CODING_ERROR("Accessing expired list editor");
412  return false;
413  }
414  return true;
415  }
416 
417  bool _Validate() const
418  {
419  if (!_listEditor) {
420  return false;
421  }
422 
423  if (IsExpired()) {
424  TF_CODING_ERROR("Accessing expired list editor");
425  return false;
426  }
427  return true;
428  }
429 
430  void _AddIfMissing(SdfListOpType op, const value_type& value)
431  {
432  ListProxy proxy(_listEditor, op);
433  size_t index = proxy.Find(value);
434  if (index == size_t(-1)) {
435  proxy.push_back(value);
436  }
437  }
438 
439  void _AddOrReplace(SdfListOpType op, const value_type& value)
440  {
441  ListProxy proxy(_listEditor, op);
442  size_t index = proxy.Find(value);
443  if (index == size_t(-1)) {
444  proxy.push_back(value);
445  }
446  else if (value != static_cast<value_type>(proxy[index])) {
447  proxy[index] = value;
448  }
449  }
450 
451  void _Prepend(SdfListOpType op, const value_type& value)
452  {
453  ListProxy proxy(_listEditor, op);
454  size_t index = proxy.Find(value);
455  if (index != 0) {
456  if (index != size_t(-1)) {
457  proxy.Erase(index);
458  }
459  proxy.insert(proxy.begin(), value);
460  }
461  }
462 
463  void _Append(SdfListOpType op, const value_type& value)
464  {
465  ListProxy proxy(_listEditor, op);
466  size_t index = proxy.Find(value);
467  if (proxy.empty() || (index != proxy.size()-1)) {
468  if (index != size_t(-1)) {
469  proxy.Erase(index);
470  }
471  proxy.push_back(value);
472  }
473  }
474 
475 private:
476  std::shared_ptr<Sdf_ListEditor<TypePolicy> > _listEditor;
477 
478  friend class Sdf_ListEditorProxyAccess;
479  template <class T> friend class SdfPyWrapListEditorProxy;
480 };
481 
482 // Cannot get from a VtValue except as the correct type.
483 template <class TP>
484 struct Vt_DefaultValueFactory<SdfListEditorProxy<TP> > {
485  static Vt_DefaultValueHolder Invoke() = delete;
486 };
487 
488 PXR_NAMESPACE_CLOSE_SCOPE
489 
490 #endif // PXR_USD_SDF_LIST_EDITOR_PROXY_H
void RemoveItemEdits(const value_type &item)
Remove all occurrences of the given item, regardless of whether the item is explicit,...
bool ClearEdits()
Removes all keys and changes the editor to have list operations.
bool HasKeys() const
Returns true if the editor has an explicit list (even if it's empty) or it has any added,...
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.
Represents a set of list editing operations.
value_vector_type GetAddedOrExplicitItems() const
Deprecated. Please use GetAppliedItems.
value_vector_type GetAppliedItems() const
Returns the effective list of items represented by the operations in this list op.
ListProxy GetAddedItems() const
Returns the items added by this list editor.
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
SdfListEditorProxy(const std::shared_ptr< Sdf_ListEditor< TypePolicy > > &listEditor)
Creates a new proxy object backed by the supplied list editor.
bool IsExplicit() const
Returns true if the editor has an explicit list, false if it has list operations.
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.
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.
DANGER DANGER DANGER
Definition: changeBlock.h:73
Represents a single list of list editing operations.
Definition: listProxy.h:59
void ReplaceItemEdits(const value_type &oldItem, const value_type &newItem)
Replace all occurrences of the given item, regardless of whether the item is explicit,...
ListProxy GetDeletedItems() const
Returns the items deleted by this list editor.
bool CopyItems(const This &other)
Copies the keys from other.
void ApplyEditsToList(value_vector_type *vec) const
Apply the edits to vec.
bool ClearEditsAndMakeExplicit()
Removes all keys and changes the editor to be explicit.
ListProxy GetExplicitItems() const
Returns the explicitly set items.
void ModifyItemEdits(CB callback)
callback is called for every key.
ListProxy GetAppendedItems() const
Returns the items appended by this list editor.
SdfListEditorProxy()
Creates a default proxy object.
ListProxy GetPrependedItems() const
Returns the items prepended by this list editor.