HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
notice.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_USD_NOTICE_H
8 #define PXR_USD_USD_NOTICE_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/usd/api.h"
12 #include "pxr/usd/usd/common.h"
13 #include "pxr/usd/usd/object.h"
14 
15 #include "pxr/usd/sdf/changeList.h"
16 #include "pxr/usd/sdf/path.h"
17 #include "pxr/base/tf/notice.h"
18 
20 
21 
22 /// \class UsdNotice
23 ///
24 /// Container class for Usd notices
25 ///
26 class UsdNotice {
27 public:
28 
29  /// Base class for UsdStage notices.
30  class StageNotice : public TfNotice {
31  public:
32  USD_API
33  StageNotice(const UsdStageWeakPtr &stage);
34  USD_API
35  ~StageNotice() override;
36 
37  /// Return the stage associated with this notice.
38  const UsdStageWeakPtr &GetStage() const { return _stage; }
39 
40  private:
41  UsdStageWeakPtr _stage;
42  };
43 
44  /// \class StageContentsChanged
45  ///
46  /// Ultra-conservative notice sent when the given UsdStage's contents
47  /// have changed in any way. This notice is sent when \em any authoring
48  /// is performed in any of the stage's participatory layers, in the
49  /// thread performing the authoring, \em after the affected UsdStage
50  /// has reconfigured itself in response to the authored changes.
51  ///
52  /// Receipt of this notice should cause clients to disregard any cached
53  /// values for properties or metadata. It does not \em necessarily imply
54  /// invalidation of UsdPrim s.
55  ///
57  public:
58  explicit StageContentsChanged(const UsdStageWeakPtr& stage)
59  : StageNotice(stage) {}
60  USD_API ~StageContentsChanged() override;
61  };
62 
63  /// \class ObjectsChanged
64  ///
65  /// Notice sent in response to authored changes that affect UsdObjects.
66  ///
67  /// The kinds of object changes are divided into these categories:
68  ///
69  /// - Object resync:
70  /// \parblock
71  /// "Resyncs" are potentially structural changes that invalidate entire
72  /// subtrees of UsdObjects (including prims and properties). For example,
73  /// if the path "/foo" is resynced, then all subpaths like "/foo/bar" and
74  /// "/foo/bar.baz" may be arbitrarily changed.
75  ///
76  /// When a prim is resynced, say "/foo/bar", it might have been created or
77  /// destroyed. Indication of possible changes flows down the resynced prim
78  /// namespace, implicitly via prim resync notices. We *do not* consider the
79  /// parent "/foo" to be resynced, as this would incorrectly imply that
80  /// some or all of "/foo/bar"'s siblings (and their descendants) have
81  /// also changed. Additionally, we do not propagate change indication to
82  /// objects associated with the changed object through relationships or
83  /// connections.
84  /// \endparblock
85  ///
86  /// - Resolved asset path resync:
87  /// \parblock
88  /// "Resolved asset path resyncs" invalidate asset paths in a subtree of
89  /// objects. Asset paths authored anywhere in this subtree of objects
90  /// (e.g. as attribute or metadata values) may now resolve to different
91  /// locations, even though the asset path authored in scene description
92  /// has not changed.
93  ///
94  /// \endparblock
95  ///
96  /// - Changed info:
97  /// \parblock
98  /// "Changed-info" means that a nonstructural change has occurred, like an
99  /// attribute value change or a value change to a metadata field not related
100  /// to composition. Unlike resyncs, changed-info notices for an object do
101  /// not imply that the subtree beneath that object have changed.
102  ///
103  /// \endparblock
104  ///
105  /// This notice provides API for two client use-cases. Clients interested
106  /// in testing whether specific objects are affected by the changes should
107  /// use the methods that return a bool, like AffectedObject(). Clients that
108  /// wish to reason about all changes as a whole should use the methods that
109  /// return a PathRange, like GetResyncedPaths().
110  ///
111  class ObjectsChanged : public StageNotice {
112 
113  public:
114  /// A type for further classifying objects that have may have been
115  /// resynced because of namespace edits.
116  enum class PrimResyncType {
117  /// These six types indicate that a resynced object was moved to
118  /// a new path, via a UsdNamespaceEditor, and that object at the
119  /// new path has the same computed prim stack as the objects at
120  /// the original path did (i.e. the new object composes the
121  /// exact same layer opinions in the exact same order as the
122  /// original object). The old path resync will be classified as a
123  /// Source and the new path resync will be classified as a
124  /// Destination.
125  RenameSource,
131 
132  /// This Delete type indicates that an object has been removed
133  /// from the stage without an indication that it was the source of a
134  /// rename and/or a reparent operation.
135  Delete,
136 
137  /// The UnchangedPrimStack type indicates that the resynced object
138  /// still exists and is effectively unchanged in that it has the
139  /// same composed prim stack as before it was resynced. This can
140  /// occur when composition arcs are changed or dependent layer specs
141  /// are moved to maintain prims of dependent stages in a
142  /// UsdNamespaceEditor edit.
144 
145  /// This type indicates all other resyncs that we cannot classify
146  /// based on namespace edit information. This other type does not
147  /// necesarily imply that we don't have a rename, reparent, noop,
148  /// etc. but rather that we cannot determine the type and need to
149  /// treat it as a full resync.
150  Other,
151 
152  /// Invalid indicates that the object has not been resynced.
153  Invalid
154  };
155 
156  /// Value type holding a list of property paths that have been renamed
157  /// via the UsdNamespaceEditor paired with the new name of the property.
158  using RenamedProperties = std::vector<std::pair<SdfPath, TfToken>>;
159 
160  private:
161  using _PathsToChangesMap =
162  std::map<SdfPath, std::vector<const SdfChangeList::Entry*>>;
163 
164  struct _PrimResyncInfo {
165  PrimResyncType resyncType;
166  SdfPath associatePath;
167  };
168  using _PrimResyncInfoMap = std::map<SdfPath, _PrimResyncInfo>;
169 
170  struct _NamespaceEditsInfo {
171  _PrimResyncInfoMap primResyncsInfo;
172  RenamedProperties renamedProperties;
173  };
174 
175  static const _PathsToChangesMap& _GetEmptyChangesMap();
176  static const _NamespaceEditsInfo& _GetEmptyNamespaceEditsInfo();
177 
178  friend class UsdStage;
179  ObjectsChanged(const UsdStageWeakPtr &stage,
180  const _PathsToChangesMap *resyncChanges,
181  const _PathsToChangesMap *infoChanges,
182  const _PathsToChangesMap *assetPathChanges,
183  const _NamespaceEditsInfo *namespaceEditsInfo)
184  : StageNotice(stage)
185  , _resyncChanges(resyncChanges)
186  , _infoChanges(infoChanges)
187  , _assetPathChanges(assetPathChanges)
188  , _namespaceEditsInfo(namespaceEditsInfo) {}
189 
190  ObjectsChanged(const UsdStageWeakPtr &stage,
191  const _PathsToChangesMap *resyncChanges);
192 
193  public:
194  USD_API ~ObjectsChanged() override;
195 
196  /// Return true if \p obj was possibly affected by the layer changes
197  /// that generated this notice. This is the case if either the object
198  /// is subject to a resync or has changed info. Equivalent to:
199  /// \code
200  /// ResyncedObject(obj) || ResolvedAssetPathsResynced(obj) || ChangedInfoOnly(obj)
201  /// \endcode
202  bool AffectedObject(const UsdObject &obj) const {
203  return ResyncedObject(obj) || ResolvedAssetPathsResynced(obj)
204  || ChangedInfoOnly(obj);
205  }
206 
207  /// Return true if \p obj was resynced by the layer changes that
208  /// generated this notice. This is the case if the object's path or an
209  /// ancestor path is present in GetResyncedPaths().
210  USD_API bool ResyncedObject(const UsdObject &obj) const;
211 
212  /// Return true if asset path values in \p obj were resynced by the
213  /// layer changes that generated this notice. This is the case if the
214  /// object's path or an ancestor path is present in
215  /// GetResolvedAssetPathsResyncedPaths().
216  USD_API bool ResolvedAssetPathsResynced(const UsdObject &obj) const;
217 
218  /// Return true if \p obj was changed but not resynced by the layer
219  /// changes that generated this notice. This is the case if this
220  /// object's exact path is present in GetChangedInfoOnlyPaths().
221  USD_API bool ChangedInfoOnly(const UsdObject &obj) const;
222 
223  /// \class PathRange
224  /// An iterable range of paths to objects that have changed.
225  ///
226  /// Users may use this object in range-based for loops, or use the
227  /// iterators to access additional information about each changed
228  /// object.
229  class PathRange
230  {
231  public:
232  /// \class iterator
233  class iterator {
234  using _UnderlyingIterator = _PathsToChangesMap::const_iterator;
235  public:
236  using iterator_category = std::forward_iterator_tag;
237  using value_type = const SdfPath&;
238  using reference = const SdfPath&;
239  using pointer = const SdfPath*;
240  using difference_type =
241  typename _UnderlyingIterator::difference_type;
242 
243  iterator() = default;
244  reference operator*() const { return dereference(); }
245  pointer operator->() const { return &(dereference()); }
246 
248  ++_underlyingIterator;
249  return *this;
250  }
251 
253  iterator result = *this;
254  ++_underlyingIterator;
255  return result;
256  }
257 
258  bool operator==(const iterator& other) const{
259  return _underlyingIterator == other._underlyingIterator;
260  }
261 
262  bool operator!=(const iterator& other) const{
263  return _underlyingIterator != other._underlyingIterator;
264  }
265 
266  /// Return the set of changed fields in layers that affected
267  /// the object at the path specified by this iterator. See
268  /// UsdNotice::ObjectsChanged::GetChangedFields for more
269  /// details.
271 
272  /// Return true if the object at the path specified by this
273  /// iterator has any changed fields, false otherwise. See
274  /// UsdNotice::ObjectsChanged::HasChangedFields for more
275  /// details.
276  USD_API bool HasChangedFields() const;
277 
278  /// Returns the underlying iterator
279  _UnderlyingIterator GetBase() const {
280  return _underlyingIterator;
281  }
282 
283  /// \deprecated Use GetBase() instead.
284  _UnderlyingIterator base() const {
285  return GetBase();
286  }
287 
288  private:
289  friend class PathRange;
290 
291  explicit iterator(_UnderlyingIterator baseIter)
292  : _underlyingIterator(baseIter) {}
293 
294  inline reference dereference() const {
295  return _underlyingIterator->first;
296  }
297 
298  _UnderlyingIterator _underlyingIterator;
299  };
300 
302 
303  PathRange() : _changes(nullptr) { }
304 
305  /// Explicit conversion to SdfPathVector for convenience
306  explicit operator SdfPathVector() const {
307  return SdfPathVector(begin(), end());
308  }
309 
310  /// Return true if this range contains any paths, false otherwise.
311  bool empty() const {
312  return !_changes || _changes->empty();
313  }
314 
315  /// Return the number of paths in this range.
316  size_t size() const {
317  return _changes ? _changes->size() : 0;
318  }
319 
320  /// Return iterator to the start of this range.
321  iterator begin() const {
322  return iterator(_changes->cbegin());
323  }
324 
325  /// Return iterator to the start of this range.
327  return iterator(_changes->cbegin());
328  }
329 
330  /// Return the end iterator for this range.
331  iterator end() const {
332  return iterator(_changes->cend());
333  }
334 
335  /// Return the end iterator for this range.
336  const_iterator cend() const {
337  return iterator(_changes->cend());
338  }
339 
340  /// Return an iterator to the specified \p path in this range if
341  /// it exists, or end() if it does not. This is potentially more
342  /// efficient than std::find(begin(), end()).
343  const_iterator find(const SdfPath& path) const {
344  return const_iterator(_changes->find(path));
345  }
346 
347  private:
348  friend class ObjectsChanged;
349  explicit PathRange(const _PathsToChangesMap* changes)
350  : _changes(changes)
351  { }
352 
353  const _PathsToChangesMap* _changes;
354  };
355 
356  /// Return the set of paths that are resynced in lexicographical order.
357  /// Resyncs imply entire subtree invalidation of all descendant prims
358  /// and properties, so this set is minimal regarding ancestors and
359  /// descendants. For example, if the path '/foo' appears in this set,
360  /// the entire subtree at '/foo' is resynced so the path '/foo/bar' will
361  /// not appear, but it should be considered resynced.
362  ///
363  /// Since object resyncs fully invalidate entire subtrees, this set of
364  /// paths subsumes all other paths. For example, if the path '/foo'
365  /// appears in this set, but an attribute value was changed at
366  /// '/foo/bar.x', this notice will only contain '/foo' in the set
367  /// returned by this path and empty sets from all other functions. This
368  /// is because the change to '/foo/bar.x' is implied by the resync of
369  /// '/foo'.
370  USD_API PathRange GetResyncedPaths() const;
371 
372  /// Return the set of paths that have only info changes (those that do
373  /// not affect the structure of cached UsdPrims on a UsdStage) in
374  /// lexicographical order. Info changes do not imply entire subtree
375  /// invalidation, so this set is not minimal regarding ancestors and
376  /// descendants, as opposed to GetResyncedPaths(). For example, both
377  /// the paths '/foo' and '/foo/bar' may appear in this set.
378  ///
379  /// \note
380  /// The "only" in "changed info only paths" was historically meant to
381  /// distinguish these paths from the object resync paths returned by
382  /// GetResyncedPaths, since the former is subsumed by the latter. It
383  /// is now slightly misleading; paths in "changed info only" are still
384  /// subsumed by "object resync" paths, but are *not* subsumed by other
385  /// types of changes, like "resolved asset path resyncs".
386  USD_API PathRange GetChangedInfoOnlyPaths() const;
387 
388  /// Return the set of paths affected by changes that may cause asset
389  /// path values to resolve to different locations, even though the asset
390  /// path authored in scene description has not changed. For example,
391  /// asset paths using expression variables may be invalidated when a
392  /// variable value is modified, even though the authored asset paths
393  /// have not changed. The set of paths are returned in lexicographical
394  /// order.
395  ///
396  /// Resolved asset path resyncs imply invalidation of asset paths within
397  /// entire subtrees including all descendant prims and properties, so
398  /// this set is minimal regarding ancestors and descendants. For
399  /// example, if the path '/foo' appears in this set, all asset paths in
400  /// the entire subtree at '/foo' are invalidated, so the path '/foo/bar'
401  /// will not appear, but asset paths on that prim should be considered
402  /// invalidated.
404 
405  /// Return the set of changed fields in layers that affected \p obj.
406  ///
407  /// This set will be empty for objects whose paths are not in
408  /// GetResyncedPaths() or GetChangedInfoOnlyPaths().
409  ///
410  /// If a field is present in this set, it does not necessarily mean the
411  /// composed value of that field on \p obj has changed. For example, if
412  /// a metadata value on \p obj is overridden in a stronger layer and
413  /// is changed in a weaker layer, that field will appear in this set.
414  /// However, since the value in the stronger layer did not change,
415  /// the composed value returned by GetMetadata() will not have changed.
417 
418  /// \overload
420 
421  /// Return true if there are any changed fields that affected \p obj,
422  /// false otherwise. See GetChangedFields for more details.
423  USD_API bool HasChangedFields(const UsdObject &obj) const;
424 
425  /// \overload
426  USD_API bool HasChangedFields(const SdfPath &path) const;
427 
428  /// Returns the type of resync that has occurred for the prim at
429  /// \p primPath.
430  ///
431  /// When prims are edited through the UsdNamespaceEditor we'll have
432  /// additional information about whether the prim resyncs that have
433  /// occurred are for prims that have been renamed, reparented, or
434  /// just adjusted to maintain composition without changing the prim
435  /// path itself. These are all resyncs that are expected to have no net
436  /// effect on the prim's composed contents relative to the original
437  /// prim. This function returns the the prim's resync type based on that
438  /// information.
439  ///
440  /// If the prim path is the source of a rename and/or reparent operation
441  /// the returned type will be a "Source" type and the
442  /// \p associatedPrimPath, if provided, will be set to the path of the
443  /// corresponding destination prim. Likewise, if the prim path is the
444  /// destination of a rename and/or reparent operation the returned type
445  /// will be a "Destination" type and the \p associatedPrimPath, if
446  /// provided, will be set to the path of the corresponding source prim.
447  /// See PrimSyncType for more information about the other return types.
449  const SdfPath &primPath,
450  SdfPath *associatedPrimPath = nullptr) const;
451 
452  /// Return the list of property paths that have been renamed via a
453  /// UsdNamespaceEditor ApplyEdits operation along with the new names of
454  /// those properties. When multiple properties have been edited, this
455  /// list will contain them in no particular order.
457  return _namespaceEditsInfo->renamedProperties;
458  }
459 
460  private:
461  const _PathsToChangesMap *_resyncChanges;
462  const _PathsToChangesMap *_infoChanges;
463  const _PathsToChangesMap *_assetPathChanges;
464  const _NamespaceEditsInfo *_namespaceEditsInfo;
465  };
466 
467  /// \class StageEditTargetChanged
468  ///
469  /// Notice sent when a stage's EditTarget has changed. Sent in the
470  /// thread that changed the target.
471  ///
473  public:
475  : StageNotice(stage) {}
476  USD_API ~StageEditTargetChanged() override;
477  };
478 
479  /// \class LayerMutingChanged
480  ///
481  /// Notice sent after a set of layers have been newly muted or unmuted.
482  /// Note this does not necessarily mean the specified layers are currently
483  /// loaded.
484  ///
485  /// LayerMutingChanged notice is sent before any UsdNotice::ObjectsChanged
486  /// or UsdNotice::StageContentsChanged notices are sent resulting from
487  /// muting or unmuting of layers.
488  ///
489  /// Note that LayerMutingChanged notice is sent even if the
490  /// muting/unmuting layer does not belong to the current stage, or is a
491  /// layer that does belong to the current stage but is not yet loaded
492  /// because it is behind an unloaded payload or unselected variant.
494  public:
495  explicit LayerMutingChanged(const UsdStageWeakPtr &stage,
496  const std::vector<std::string>& mutedLayers,
497  const std::vector<std::string>& unmutedLayers)
498  : StageNotice(stage),
499  _mutedLayers(mutedLayers),
500  _unMutedLayers(unmutedLayers) {}
501 
502  USD_API ~LayerMutingChanged() override;
503 
504  /// Returns the identifier of the layers that were muted.
505  ///
506  /// The stage's resolver context must be bound when looking up
507  /// layers using the returned identifiers to ensure the same layers
508  /// that would be used by the stage are found.
509  const std::vector<std::string>& GetMutedLayers() const {
510  return _mutedLayers;
511  }
512 
513  /// Returns the identifier of the layers that were unmuted.
514  ///
515  /// The stage's resolver context must be bound when looking up
516  /// layers using the returned identifiers to ensure the same layers
517  /// that would be used by the stage are found.
518  const std::vector<std::string>& GetUnmutedLayers() const {
519  return _unMutedLayers;
520  }
521 
522  private:
523  const std::vector<std::string>& _mutedLayers;
524  const std::vector<std::string>& _unMutedLayers;
525  };
526 
527 };
528 
529 
531 
532 #endif // PXR_USD_USD_NOTICE_H
bool operator!=(const iterator &other) const
Definition: notice.h:262
StageContentsChanged(const UsdStageWeakPtr &stage)
Definition: notice.h:58
size_t size() const
Return the number of paths in this range.
Definition: notice.h:316
const_iterator cend() const
Return the end iterator for this range.
Definition: notice.h:336
#define USD_API
Definition: api.h:23
bool AffectedObject(const UsdObject &obj) const
Definition: notice.h:202
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
USD_API ~ObjectsChanged() override
bool empty() const
Return true if this range contains any paths, false otherwise.
Definition: notice.h:311
USD_API StageNotice(const UsdStageWeakPtr &stage)
const UsdStageWeakPtr & GetStage() const
Return the stage associated with this notice.
Definition: notice.h:38
**But if you need a result
Definition: thread.h:622
const std::vector< std::string > & GetMutedLayers() const
Definition: notice.h:509
UsdStagePtr UsdStageWeakPtr
Definition: common.h:38
USD_API TfTokenVector GetChangedFields() const
const std::vector< std::string > & GetUnmutedLayers() const
Definition: notice.h:518
const_iterator cbegin() const
Return iterator to the start of this range.
Definition: notice.h:326
USD_API bool ResolvedAssetPathsResynced(const UsdObject &obj) const
StageEditTargetChanged(const UsdStageWeakPtr &stage)
Definition: notice.h:474
std::forward_iterator_tag iterator_category
Definition: notice.h:236
USD_API ~StageEditTargetChanged() override
Base class for UsdStage notices.
Definition: notice.h:30
_UnderlyingIterator GetBase() const
Returns the underlying iterator.
Definition: notice.h:279
USD_API bool HasChangedFields(const UsdObject &obj) const
std::vector< class SdfPath > SdfPathVector
USD_API ~StageContentsChanged() override
USD_API bool ChangedInfoOnly(const UsdObject &obj) const
Invalid indicates that the object has not been resynced.
USD_API ~StageNotice() override
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
typename _UnderlyingIterator::difference_type difference_type
Definition: notice.h:241
USD_API PrimResyncType GetPrimResyncType(const SdfPath &primPath, SdfPath *associatedPrimPath=nullptr) const
Definition: path.h:273
iterator begin() const
Return iterator to the start of this range.
Definition: notice.h:321
USD_API ~LayerMutingChanged() override
std::vector< std::pair< SdfPath, TfToken >> RenamedProperties
Definition: notice.h:158
const RenamedProperties & GetRenamedProperties() const
Definition: notice.h:456
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
USD_API PathRange GetChangedInfoOnlyPaths() const
USD_API PathRange GetResyncedPaths() const
USD_API TfTokenVector GetChangedFields(const UsdObject &obj) const
LayerMutingChanged(const UsdStageWeakPtr &stage, const std::vector< std::string > &mutedLayers, const std::vector< std::string > &unmutedLayers)
Definition: notice.h:495
const_iterator find(const SdfPath &path) const
Definition: notice.h:343
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool operator==(const iterator &other) const
Definition: notice.h:258
iterator end() const
Return the end iterator for this range.
Definition: notice.h:331
USD_API bool ResyncedObject(const UsdObject &obj) const
USD_API PathRange GetResolvedAssetPathsResyncedPaths() const
_UnderlyingIterator base() const
Definition: notice.h:284