HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
namespaceEdit.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_NAMESPACE_EDIT_H
8 #define PXR_USD_SDF_NAMESPACE_EDIT_H
9 
10 /// \file sdf/namespaceEdit.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/sdf/api.h"
14 #include "pxr/usd/sdf/path.h"
15 
16 #include <functional>
17 #include <iosfwd>
18 #include <string>
19 #include <vector>
20 
22 
23 /// \class SdfNamespaceEdit
24 ///
25 /// A single namespace edit. It supports renaming, reparenting, reparenting
26 /// with a rename, reordering, and removal.
27 ///
29 public:
31  typedef SdfPath Path;
32  typedef int Index;
33 
34  /// Special index that means at the end.
35  static const Index AtEnd = -1;
36 
37  /// Special index that means don't move. It's only meaningful when
38  /// renaming. In other cases implementations may assume \c AtEnd.
39  static const Index Same = -2;
40 
41  /// The default edit maps the empty path to the empty path.
43 
44  /// The fully general edit.
45  SdfNamespaceEdit(const Path& currentPath_, const Path& newPath_,
46  Index index_ = AtEnd) :
47  currentPath(currentPath_), newPath(newPath_), index(index_) { }
48 
49  /// Returns a namespace edit that removes the object at \p currentPath.
50  static This Remove(const Path& currentPath)
51  {
52  return This(currentPath, Path::EmptyPath());
53  }
54 
55  /// Returns a namespace edit that renames the prim or property at
56  /// \p currentPath to \p name
57  static This Rename(const Path& currentPath, const TfToken& name)
58  {
59  return This(currentPath, currentPath.ReplaceName(name), Same);
60  }
61 
62  /// Returns a namespace edit to reorder the prim or property at
63  /// \p currentPath to index \p index.
65  {
66  return This(currentPath, currentPath, index);
67  }
68 
69  /// Returns a namespace edit to reparent the prim or property at
70  /// \p currentPath to be under \p newParentPath at index \p index.
71  static This Reparent(const Path& currentPath,
72  const Path& newParentPath,
73  Index index)
74  {
75  return This(currentPath,
76  currentPath.ReplacePrefix(currentPath.GetParentPath(),
77  newParentPath),
78  index);
79  }
80 
81  /// Returns a namespace edit to reparent the prim or property at
82  /// \p currentPath to be under \p newParentPath at index \p index
83  /// with the name \p name.
85  const Path& newParentPath,
86  const TfToken& name,
87  Index index)
88  {
89  return This(currentPath,
90  currentPath.ReplacePrefix(currentPath.GetParentPath(),
91  newParentPath).
92  ReplaceName(name),
93  index);
94  }
95 
96  SDF_API bool operator==(const This& rhs) const;
97  SDF_API bool operator!=(const This& rhs) const;
98 
99 public:
100  Path currentPath; ///< Path of the object when this edit starts.
101  Path newPath; ///< Path of the object when this edit ends.
102  Index index; ///< Index for prim insertion.
103 };
104 
105 /// A sequence of \c SdfNamespaceEdit.
106 typedef std::vector<SdfNamespaceEdit> SdfNamespaceEditVector;
107 
108 SDF_API std::ostream& operator<<(std::ostream&, const SdfNamespaceEdit&);
109 SDF_API std::ostream& operator<<(std::ostream&, const SdfNamespaceEditVector&);
110 
111 /// \struct SdfNamespaceEditDetail
112 ///
113 /// Detailed information about a namespace edit.
114 ///
116 public:
117  /// Validity of an edit.
118  enum Result {
119  Error, ///< Edit will fail.
120  Unbatched, ///< Edit will succeed but not batched.
121  Okay, ///< Edit will succeed as a batch.
122  };
123 
126  const std::string& reason);
127 
128  SDF_API bool operator==(const SdfNamespaceEditDetail& rhs) const;
129  SDF_API bool operator!=(const SdfNamespaceEditDetail& rhs) const;
130 
131 public:
132  Result result; ///< Validity.
133  SdfNamespaceEdit edit; ///< The edit.
134  std::string reason; ///< The reason the edit will not succeed cleanly.
135 };
136 
137 /// A sequence of \c SdfNamespaceEditDetail.
138 typedef std::vector<SdfNamespaceEditDetail> SdfNamespaceEditDetailVector;
139 
140 SDF_API std::ostream& operator<<(std::ostream&, const SdfNamespaceEditDetail&);
141 SDF_API std::ostream& operator<<(std::ostream&, const SdfNamespaceEditDetailVector&);
142 
143 /// Combine two results, yielding Error over Unbatched over Okay.
144 inline
149 {
150  return lhs < rhs ? lhs : rhs;
151 }
152 
153 /// Combine a result with Error, yielding Error over Unbatched over Okay.
154 inline
157 {
159 }
160 
161 /// Combine a result with Unbatched, yielding Error over Unbatched over Okay.
162 inline
165 {
167 }
168 
169 /// \class SdfBatchNamespaceEdit
170 ///
171 /// A description of an arbitrarily complex namespace edit.
172 ///
173 /// A \c SdfBatchNamespaceEdit object describes zero or more namespace edits.
174 /// Various types providing a namespace will allow the edits to be applied
175 /// in a single operation and also allow testing if this will work.
176 ///
177 /// Clients are encouraged to group several edits into one object because
178 /// that may allow more efficient processing of the edits. If, for example,
179 /// you need to reparent several prims it may be faster to add all of the
180 /// reparents to a single \c SdfBatchNamespaceEdit and apply them at once
181 /// than to apply each separately.
182 ///
183 /// Objects that allow applying edits are free to apply the edits in any way
184 /// and any order they see fit but they should guarantee that the resulting
185 /// namespace will be as if each edit was applied one at a time in the order
186 /// they were added.
187 ///
188 /// Note that the above rule permits skipping edits that have no effect or
189 /// generate a non-final state. For example, if renaming A to B then to C
190 /// we could just rename A to C. This means notices may be elided. However,
191 /// implementations must not elide notices that contain information about any
192 /// edit that clients must be able to know but otherwise cannot determine.
193 ///
195 public:
196  /// Create an empty sequence of edits.
198  SDF_API SdfBatchNamespaceEdit(const SdfBatchNamespaceEdit&);
201 
202  SDF_API SdfBatchNamespaceEdit& operator=(const SdfBatchNamespaceEdit&);
203 
204  /// Add a namespace edit.
205  void Add(const SdfNamespaceEdit& edit)
206  {
207  _edits.push_back(edit);
208  }
209 
210  /// Add a namespace edit.
211  void Add(const SdfNamespaceEdit::Path& currentPath,
212  const SdfNamespaceEdit::Path& newPath,
214  {
215  Add(SdfNamespaceEdit(currentPath, newPath, index));
216  }
217 
218  /// Returns the edits.
220  {
221  return _edits;
222  }
223 
224  /// Functor that returns \c true iff an object exists at the given path.
225  typedef std::function<bool(const SdfPath&)> HasObjectAtPath;
226 
227  /// Functor that returns \c true iff the namespace edit will succeed.
228  /// If not it returns \c false and sets the string argument.
229  typedef std::function<bool(const SdfNamespaceEdit&,std::string*)> CanEdit;
230 
231  /// Validate the edits and generate a possibly more efficient edit
232  /// sequence. Edits are treated as if they were performed one at time
233  /// in sequence, therefore each edit occurs in the namespace resulting
234  /// from all previous edits.
235  ///
236  /// Editing the descendants of the object in each edit is implied. If
237  /// an object is removed then the new path will be empty. If an object
238  /// is removed after being otherwise edited, the other edits will be
239  /// processed and included in \p processedEdits followed by the removal.
240  /// This allows clients to fixup references to point to the object's
241  /// final location prior to removal.
242  ///
243  /// This function needs help to determine if edits are allowed. The
244  /// callbacks provide that help. \p hasObjectAtPath returns \c true
245  /// iff there's an object at the given path. This path will be in the
246  /// original namespace not any intermediate or final namespace.
247  /// \p canEdit returns \c true iff the object at the current path can
248  /// be namespace edited to the new path, ignoring whether an object
249  /// already exists at the new path. Both paths are in the original
250  /// namespace. If it returns \c false it should set the string to the
251  /// reason why the edit isn't allowed. It should not write either path
252  /// to the string.
253  ///
254  /// If \p hasObjectAtPath is invalid then this assumes objects exist
255  /// where they should and don't exist where they shouldn't. Use this
256  /// with care. If \p canEdit in invalid then it's assumed all edits
257  /// are valid.
258  ///
259  /// If \p fixBackpointers is \c true then target/connection paths are
260  /// expected to be in the intermediate namespace resulting from all
261  /// previous edits. If \c false and any current or new path contains a
262  /// target or connection path that has been edited then this will
263  /// generate an error.
264  ///
265  /// This method returns \c true if the edits are allowed and sets
266  /// \p processedEdits to a new edit sequence at least as efficient as
267  /// the input sequence. If not allowed it returns \c false and appends
268  /// reasons why not to \p details.
269  SDF_API
270  bool Process(SdfNamespaceEditVector* processedEdits,
271  const HasObjectAtPath& hasObjectAtPath,
272  const CanEdit& canEdit,
273  SdfNamespaceEditDetailVector* details = NULL,
274  bool fixBackpointers = true) const;
275 
276 private:
277  SdfNamespaceEditVector _edits;
278 };
279 
281 
282 #endif // PXR_USD_SDF_NAMESPACE_EDIT_H
SDF_API SdfBatchNamespaceEdit()
Create an empty sequence of edits.
std::vector< SdfNamespaceEditDetail > SdfNamespaceEditDetailVector
A sequence of SdfNamespaceEditDetail.
std::string reason
The reason the edit will not succeed cleanly.
Result
Validity of an edit.
SDF_API bool Process(SdfNamespaceEditVector *processedEdits, const HasObjectAtPath &hasObjectAtPath, const CanEdit &canEdit, SdfNamespaceEditDetailVector *details=NULL, bool fixBackpointers=true) const
SdfNamespaceEdit(const Path &currentPath_, const Path &newPath_, Index index_=AtEnd)
The fully general edit.
Definition: namespaceEdit.h:45
SDF_API SdfNamespaceEditDetail()
static This Rename(const Path &currentPath, const TfToken &name)
Definition: namespaceEdit.h:57
SdfNamespaceEditDetail::Result CombineResult(SdfNamespaceEditDetail::Result lhs, SdfNamespaceEditDetail::Result rhs)
Combine two results, yielding Error over Unbatched over Okay.
Path currentPath
Path of the object when this edit starts.
Index index
Index for prim insertion.
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().
Definition: token.h:70
static const Index Same
Definition: namespaceEdit.h:39
SdfNamespaceEdit edit
The edit.
SdfNamespaceEditDetail::Result CombineUnbatched(SdfNamespaceEditDetail::Result other)
Combine a result with Unbatched, yielding Error over Unbatched over Okay.
SdfNamespaceEdit This
Definition: namespaceEdit.h:30
SdfNamespaceEditDetail::Result CombineError(SdfNamespaceEditDetail::Result)
Combine a result with Error, yielding Error over Unbatched over Okay.
void Add(const SdfNamespaceEdit &edit)
Add a namespace edit.
SDF_API std::ostream & operator<<(std::ostream &, const SdfNamespaceEdit &)
SDF_API bool operator==(const This &rhs) const
Edit will succeed as a batch.
Edit will succeed but not batched.
Result result
Validity.
std::vector< SdfNamespaceEdit > SdfNamespaceEditVector
A sequence of SdfNamespaceEdit.
GLuint const GLchar * name
Definition: glcorearb.h:786
Definition: path.h:273
SDF_API bool operator==(const SdfNamespaceEditDetail &rhs) const
#define SDF_API
Definition: api.h:23
std::function< bool(const SdfPath &)> HasObjectAtPath
Functor that returns true iff an object exists at the given path.
static This ReparentAndRename(const Path &currentPath, const Path &newParentPath, const TfToken &name, Index index)
Definition: namespaceEdit.h:84
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
static This Remove(const Path &currentPath)
Returns a namespace edit that removes the object at currentPath.
Definition: namespaceEdit.h:50
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
SDF_API SdfPath GetParentPath() const
SDF_API SdfBatchNamespaceEdit & operator=(const SdfBatchNamespaceEdit &)
Path newPath
Path of the object when this edit ends.
const SdfNamespaceEditVector & GetEdits() const
Returns the edits.
SdfNamespaceEdit()
The default edit maps the empty path to the empty path.
Definition: namespaceEdit.h:42
SDF_API bool operator!=(const This &rhs) const
static const Index AtEnd
Special index that means at the end.
Definition: namespaceEdit.h:35
static This Reorder(const Path &currentPath, Index index)
Definition: namespaceEdit.h:64
SDF_API ~SdfBatchNamespaceEdit()
std::function< bool(const SdfNamespaceEdit &, std::string *)> CanEdit
SDF_API bool operator!=(const SdfNamespaceEditDetail &rhs) const
SDF_API SdfPath ReplaceName(TfToken const &newName) const
void Add(const SdfNamespaceEdit::Path &currentPath, const SdfNamespaceEdit::Path &newPath, SdfNamespaceEdit::Index index=SdfNamespaceEdit::AtEnd)
Add a namespace edit.
SDF_API SdfPath ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix, bool fixTargetPaths=true) const
static This Reparent(const Path &currentPath, const Path &newParentPath, Index index)
Definition: namespaceEdit.h:71