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 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_USD_NOTICE_H
25 #define PXR_USD_USD_NOTICE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usd/api.h"
29 #include "pxr/usd/usd/common.h"
30 #include "pxr/usd/usd/object.h"
31 
32 #include "pxr/usd/sdf/changeList.h"
33 #include "pxr/usd/sdf/path.h"
34 #include "pxr/base/tf/notice.h"
35 
37 
38 
39 /// \class UsdNotice
40 ///
41 /// Container class for Usd notices
42 ///
43 class UsdNotice {
44 public:
45 
46  /// Base class for UsdStage notices.
47  class StageNotice : public TfNotice {
48  public:
49  USD_API
50  StageNotice(const UsdStageWeakPtr &stage);
51  USD_API
52  virtual ~StageNotice();
53 
54  /// Return the stage associated with this notice.
55  const UsdStageWeakPtr &GetStage() const { return _stage; }
56 
57  private:
58  UsdStageWeakPtr _stage;
59  };
60 
61  /// \class StageContentsChanged
62  ///
63  /// Ultra-conservative notice sent when the given UsdStage's contents
64  /// have changed in any way. This notice is sent when \em any authoring
65  /// is performed in any of the stage's participatory layers, in the
66  /// thread performing the authoring, \em after the affected UsdStage
67  /// has reconfigured itself in response to the authored changes.
68  ///
69  /// Receipt of this notice should cause clients to disregard any cached
70  /// values for properties or metadata. It does not \em necessarily imply
71  /// invalidation of UsdPrim s.
72  ///
74  public:
75  explicit StageContentsChanged(const UsdStageWeakPtr& stage)
76  : StageNotice(stage) {}
78  };
79 
80  /// \class ObjectsChanged
81  ///
82  /// Notice sent in response to authored changes that affect UsdObjects.
83  ///
84  /// The kinds of object changes are divided into these categories:
85  ///
86  /// - Object resync:
87  /// \parblock
88  /// "Resyncs" are potentially structural changes that invalidate entire
89  /// subtrees of UsdObjects (including prims and properties). For example,
90  /// if the path "/foo" is resynced, then all subpaths like "/foo/bar" and
91  /// "/foo/bar.baz" may be arbitrarily changed.
92  ///
93  /// When a prim is resynced, say "/foo/bar", it might have been created or
94  /// destroyed. Indication of possible changes flows down the resynced prim
95  /// namespace, implicitly via prim resync notices. We *do not* consider the
96  /// parent "/foo" to be resynced, as this would incorrectly imply that
97  /// some or all of "/foo/bar"'s siblings (and their descendants) have
98  /// also changed. Additionally, we do not propagate change indication to
99  /// objects associated with the changed object through relationships or
100  /// connections.
101  /// \endparblock
102  ///
103  /// - Resolved asset path resync:
104  /// \parblock
105  /// "Resolved asset path resyncs" invalidate asset paths in a subtree of
106  /// objects. Asset paths authored anywhere in this subtree of objects
107  /// (e.g. as attribute or metadata values) may now resolve to different
108  /// locations, even though the asset path authored in scene description
109  /// has not changed.
110  ///
111  /// \endparblock
112  ///
113  /// - Changed info:
114  /// \parblock
115  /// "Changed-info" means that a nonstructural change has occurred, like an
116  /// attribute value change or a value change to a metadata field not related
117  /// to composition. Unlike resyncs, changed-info notices for an object do
118  /// not imply that the subtree beneath that object have changed.
119  ///
120  /// \endparblock
121  ///
122  /// This notice provides API for two client use-cases. Clients interested
123  /// in testing whether specific objects are affected by the changes should
124  /// use the methods that return a bool, like AffectedObject(). Clients that
125  /// wish to reason about all changes as a whole should use the methods that
126  /// return a PathRange, like GetResyncedPaths().
127  ///
128  class ObjectsChanged : public StageNotice {
129  using _PathsToChangesMap =
130  std::map<SdfPath, std::vector<const SdfChangeList::Entry*>>;
131 
132  static const _PathsToChangesMap& _GetEmptyChangesMap();
133 
134  friend class UsdStage;
135  ObjectsChanged(const UsdStageWeakPtr &stage,
136  const _PathsToChangesMap *resyncChanges,
137  const _PathsToChangesMap *infoChanges,
138  const _PathsToChangesMap *assetPathChanges)
139  : StageNotice(stage)
140  , _resyncChanges(resyncChanges)
141  , _infoChanges(infoChanges)
142  , _assetPathChanges(assetPathChanges) {}
143 
144  ObjectsChanged(const UsdStageWeakPtr &stage,
145  const _PathsToChangesMap *resyncChanges);
146 
147  public:
148  USD_API virtual ~ObjectsChanged();
149 
150  /// Return true if \p obj was possibly affected by the layer changes
151  /// that generated this notice. This is the case if either the object
152  /// is subject to a resync or has changed info. Equivalent to:
153  /// \code
154  /// ResyncedObject(obj) || ResolvedAssetPathsResynced(obj) || ChangedInfoOnly(obj)
155  /// \endcode
156  bool AffectedObject(const UsdObject &obj) const {
157  return ResyncedObject(obj) || ResolvedAssetPathsResynced(obj)
158  || ChangedInfoOnly(obj);
159  }
160 
161  /// Return true if \p obj was resynced by the layer changes that
162  /// generated this notice. This is the case if the object's path or an
163  /// ancestor path is present in GetResyncedPaths().
164  USD_API bool ResyncedObject(const UsdObject &obj) const;
165 
166  /// Return true if asset path values in \p obj were resynced by the
167  /// layer changes that generated this notice. This is the case if the
168  /// object's path or an ancestor path is present in
169  /// GetResolvedAssetPathsResyncedPaths().
170  USD_API bool ResolvedAssetPathsResynced(const UsdObject &obj) const;
171 
172  /// Return true if \p obj was changed but not resynced by the layer
173  /// changes that generated this notice. This is the case if this
174  /// object's exact path is present in GetChangedInfoOnlyPaths().
175  USD_API bool ChangedInfoOnly(const UsdObject &obj) const;
176 
177  /// \class PathRange
178  /// An iterable range of paths to objects that have changed.
179  ///
180  /// Users may use this object in range-based for loops, or use the
181  /// iterators to access additional information about each changed
182  /// object.
183  class PathRange
184  {
185  public:
186  /// \class iterator
187  class iterator {
188  using _UnderlyingIterator = _PathsToChangesMap::const_iterator;
189  public:
190  using iterator_category = std::forward_iterator_tag;
191  using value_type = const SdfPath&;
192  using reference = const SdfPath&;
193  using pointer = const SdfPath*;
194  using difference_type =
195  typename _UnderlyingIterator::difference_type;
196 
197  iterator() = default;
198  reference operator*() const { return dereference(); }
199  pointer operator->() const { return &(dereference()); }
200 
202  ++_underlyingIterator;
203  return *this;
204  }
205 
207  iterator result = *this;
208  ++_underlyingIterator;
209  return result;
210  }
211 
212  bool operator==(const iterator& other) const{
213  return _underlyingIterator == other._underlyingIterator;
214  }
215 
216  bool operator!=(const iterator& other) const{
217  return _underlyingIterator != other._underlyingIterator;
218  }
219 
220  /// Return the set of changed fields in layers that affected
221  /// the object at the path specified by this iterator. See
222  /// UsdNotice::ObjectsChanged::GetChangedFields for more
223  /// details.
225 
226  /// Return true if the object at the path specified by this
227  /// iterator has any changed fields, false otherwise. See
228  /// UsdNotice::ObjectsChanged::HasChangedFields for more
229  /// details.
230  USD_API bool HasChangedFields() const;
231 
232  /// Returns the underlying iterator
233  _UnderlyingIterator GetBase() const {
234  return _underlyingIterator;
235  }
236 
237  /// \deprecated Use GetBase() instead.
238  _UnderlyingIterator base() const {
239  return GetBase();
240  }
241 
242  private:
243  friend class PathRange;
244 
245  explicit iterator(_UnderlyingIterator baseIter)
246  : _underlyingIterator(baseIter) {}
247 
248  inline reference dereference() const {
249  return _underlyingIterator->first;
250  }
251 
252  _UnderlyingIterator _underlyingIterator;
253  };
254 
256 
257  PathRange() : _changes(nullptr) { }
258 
259  /// Explicit conversion to SdfPathVector for convenience
260  explicit operator SdfPathVector() const {
261  return SdfPathVector(begin(), end());
262  }
263 
264  /// Return true if this range contains any paths, false otherwise.
265  bool empty() const {
266  return !_changes || _changes->empty();
267  }
268 
269  /// Return the number of paths in this range.
270  size_t size() const {
271  return _changes ? _changes->size() : 0;
272  }
273 
274  /// Return iterator to the start of this range.
275  iterator begin() const {
276  return iterator(_changes->cbegin());
277  }
278 
279  /// Return iterator to the start of this range.
281  return iterator(_changes->cbegin());
282  }
283 
284  /// Return the end iterator for this range.
285  iterator end() const {
286  return iterator(_changes->cend());
287  }
288 
289  /// Return the end iterator for this range.
290  const_iterator cend() const {
291  return iterator(_changes->cend());
292  }
293 
294  /// Return an iterator to the specified \p path in this range if
295  /// it exists, or end() if it does not. This is potentially more
296  /// efficient than std::find(begin(), end()).
297  const_iterator find(const SdfPath& path) const {
298  return const_iterator(_changes->find(path));
299  }
300 
301  private:
302  friend class ObjectsChanged;
303  explicit PathRange(const _PathsToChangesMap* changes)
304  : _changes(changes)
305  { }
306 
307  const _PathsToChangesMap* _changes;
308  };
309 
310  /// Return the set of paths that are resynced in lexicographical order.
311  /// Resyncs imply entire subtree invalidation of all descendant prims
312  /// and properties, so this set is minimal regarding ancestors and
313  /// descendants. For example, if the path '/foo' appears in this set,
314  /// the entire subtree at '/foo' is resynced so the path '/foo/bar' will
315  /// not appear, but it should be considered resynced.
316  ///
317  /// Since object resyncs fully invalidate entire subtrees, this set of
318  /// paths subsumes all other paths. For example, if the path '/foo'
319  /// appears in this set, but an attribute value was changed at
320  /// '/foo/bar.x', this notice will only contain '/foo' in the set
321  /// returned by this path and empty sets from all other functions. This
322  /// is because the change to '/foo/bar.x' is implied by the resync of
323  /// '/foo'.
324  USD_API PathRange GetResyncedPaths() const;
325 
326  /// Return the set of paths that have only info changes (those that do
327  /// not affect the structure of cached UsdPrims on a UsdStage) in
328  /// lexicographical order. Info changes do not imply entire subtree
329  /// invalidation, so this set is not minimal regarding ancestors and
330  /// descendants, as opposed to GetResyncedPaths(). For example, both
331  /// the paths '/foo' and '/foo/bar' may appear in this set.
332  ///
333  /// \note
334  /// The "only" in "changed info only paths" was historically meant to
335  /// distinguish these paths from the object resync paths returned by
336  /// GetResyncedPaths, since the former is subsumed by the latter. It
337  /// is now slightly misleading; paths in "changed info only" are still
338  /// subsumed by "object resync" paths, but are *not* subsumed by other
339  /// types of changes, like "resolved asset path resyncs".
340  USD_API PathRange GetChangedInfoOnlyPaths() const;
341 
342  /// Return the set of paths affected by changes that may cause asset
343  /// path values to resolve to different locations, even though the asset
344  /// path authored in scene description has not changed. For example,
345  /// asset paths using expression variables may be invalidated when a
346  /// variable value is modified, even though the authored asset paths
347  /// have not changed. The set of paths are returned in lexicographical
348  /// order.
349  ///
350  /// Resolved asset path resyncs imply invalidation of asset paths within
351  /// entire subtrees including all descendant prims and properties, so
352  /// this set is minimal regarding ancestors and descendants. For
353  /// example, if the path '/foo' appears in this set, all asset paths in
354  /// the entire subtree at '/foo' are invalidated, so the path '/foo/bar'
355  /// will not appear, but asset paths on that prim should be considered
356  /// invalidated.
358 
359  /// Return the set of changed fields in layers that affected \p obj.
360  ///
361  /// This set will be empty for objects whose paths are not in
362  /// GetResyncedPaths() or GetChangedInfoOnlyPaths().
363  ///
364  /// If a field is present in this set, it does not necessarily mean the
365  /// composed value of that field on \p obj has changed. For example, if
366  /// a metadata value on \p obj is overridden in a stronger layer and
367  /// is changed in a weaker layer, that field will appear in this set.
368  /// However, since the value in the stronger layer did not change,
369  /// the composed value returned by GetMetadata() will not have changed.
371 
372  /// \overload
374 
375  /// Return true if there are any changed fields that affected \p obj,
376  /// false otherwise. See GetChangedFields for more details.
377  USD_API bool HasChangedFields(const UsdObject &obj) const;
378 
379  /// \overload
380  USD_API bool HasChangedFields(const SdfPath &path) const;
381 
382  private:
383  const _PathsToChangesMap *_resyncChanges;
384  const _PathsToChangesMap *_infoChanges;
385  const _PathsToChangesMap *_assetPathChanges;
386  };
387 
388  /// \class StageEditTargetChanged
389  ///
390  /// Notice sent when a stage's EditTarget has changed. Sent in the
391  /// thread that changed the target.
392  ///
394  public:
396  : StageNotice(stage) {}
398  };
399 
400  /// \class LayerMutingChanged
401  ///
402  /// Notice sent after a set of layers have been newly muted or unmuted.
403  /// Note this does not necessarily mean the specified layers are currently
404  /// loaded.
405  ///
406  /// LayerMutingChanged notice is sent before any UsdNotice::ObjectsChanged
407  /// or UsdNotice::StageContentsChanged notices are sent resulting from
408  /// muting or unmuting of layers.
409  ///
410  /// Note that LayerMutingChanged notice is sent even if the
411  /// muting/unmuting layer does not belong to the current stage, or is a
412  /// layer that does belong to the current stage but is not yet loaded
413  /// because it is behind an unloaded payload or unselected variant.
415  public:
416  explicit LayerMutingChanged(const UsdStageWeakPtr &stage,
417  const std::vector<std::string>& mutedLayers,
418  const std::vector<std::string>& unmutedLayers)
419  : StageNotice(stage),
420  _mutedLayers(mutedLayers),
421  _unMutedLayers(unmutedLayers) {}
422 
423  USD_API virtual ~LayerMutingChanged();
424 
425  /// Returns the identifier of the layers that were muted.
426  ///
427  /// The stage's resolver context must be bound when looking up
428  /// layers using the returned identifiers to ensure the same layers
429  /// that would be used by the stage are found.
430  const std::vector<std::string>& GetMutedLayers() const {
431  return _mutedLayers;
432  }
433 
434  /// Returns the identifier of the layers that were unmuted.
435  ///
436  /// The stage's resolver context must be bound when looking up
437  /// layers using the returned identifiers to ensure the same layers
438  /// that would be used by the stage are found.
439  const std::vector<std::string>& GetUnmutedLayers() const {
440  return _unMutedLayers;
441  }
442 
443  private:
444  const std::vector<std::string>& _mutedLayers;
445  const std::vector<std::string>& _unMutedLayers;
446  };
447 
448 };
449 
450 
452 
453 #endif // PXR_USD_USD_NOTICE_H
bool operator!=(const iterator &other) const
Definition: notice.h:216
StageContentsChanged(const UsdStageWeakPtr &stage)
Definition: notice.h:75
size_t size() const
Return the number of paths in this range.
Definition: notice.h:270
const_iterator cend() const
Return the end iterator for this range.
Definition: notice.h:290
#define USD_API
Definition: api.h:40
bool AffectedObject(const UsdObject &obj) const
Definition: notice.h:156
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
bool empty() const
Return true if this range contains any paths, false otherwise.
Definition: notice.h:265
USD_API StageNotice(const UsdStageWeakPtr &stage)
const UsdStageWeakPtr & GetStage() const
Return the stage associated with this notice.
Definition: notice.h:55
**But if you need a result
Definition: thread.h:613
const std::vector< std::string > & GetMutedLayers() const
Definition: notice.h:430
UsdStagePtr UsdStageWeakPtr
Definition: common.h:55
USD_API TfTokenVector GetChangedFields() const
const std::vector< std::string > & GetUnmutedLayers() const
Definition: notice.h:439
const_iterator cbegin() const
Return iterator to the start of this range.
Definition: notice.h:280
USD_API bool ResolvedAssetPathsResynced(const UsdObject &obj) const
StageEditTargetChanged(const UsdStageWeakPtr &stage)
Definition: notice.h:395
std::forward_iterator_tag iterator_category
Definition: notice.h:190
virtual USD_API ~LayerMutingChanged()
Base class for UsdStage notices.
Definition: notice.h:47
_UnderlyingIterator GetBase() const
Returns the underlying iterator.
Definition: notice.h:233
USD_API bool HasChangedFields(const UsdObject &obj) const
virtual USD_API ~StageContentsChanged()
USD_API bool ChangedInfoOnly(const UsdObject &obj) const
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:457
typename _UnderlyingIterator::difference_type difference_type
Definition: notice.h:195
Definition: path.h:290
iterator begin() const
Return iterator to the start of this range.
Definition: notice.h:275
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:211
virtual USD_API ~StageNotice()
virtual USD_API ~ObjectsChanged()
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
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:416
const_iterator find(const SdfPath &path) const
Definition: notice.h:297
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
bool operator==(const iterator &other) const
Definition: notice.h:212
iterator end() const
Return the end iterator for this range.
Definition: notice.h:285
USD_API bool ResyncedObject(const UsdObject &obj) const
USD_API PathRange GetResolvedAssetPathsResyncedPaths() const
_UnderlyingIterator base() const
Definition: notice.h:238
virtual USD_API ~StageEditTargetChanged()