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