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