HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dataSourceLocator.h
Go to the documentation of this file.
1 //
2 // Copyright 2021 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_IMAGING_HD_DATASOURCELOCATOR_H
8 #define PXR_IMAGING_HD_DATASOURCELOCATOR_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/base/tf/token.h"
14 #include "pxr/base/tf/hash.h"
15 
16 #include "pxr/imaging/hd/api.h"
17 
18 #include <iosfwd>
19 
21 
22 #define HD_DATA_SOURCE_LOCATOR_SENTINEL_TOKENS \
23  ((container, "__containerDataSource"))
24 
25 /// Special tokens in a data source locator.
26 ///
27 /// HdDataSourceLocatorSentinelTokens->container indicates that
28 /// the container data source needs to be refetched even though none of
29 /// its contained data sources have changed unless indicated by another
30 /// data source locator.
31 ///
32 /// For example, assume that MyFilteringSceneIndex::GetPrim("/MyPrim")
33 /// previously returned the result from the input scene index but now
34 /// returns
35 /// HdContainerDataSourceEditor(_GetInputScene()->GetPrim("/MyPrim"))
36 /// .Set(HdDataSourceLocator("foo", "bar", "mySource"), mySource)
37 /// .Finish().
38 /// Then it needs to send prims dirtied with
39 /// HdDataSourceLocatorSet{
40 /// HdDataSourceLocator(
41 /// HdDataSourceLocatorSentinelTokens->container),
42 /// HdDataSourceLocator(
43 /// "foo", HdDataSourceLocatorSentinelTokens->container),
44 /// HdDataSourceLocator(
45 /// "foo", "bar", HdDataSourceLocatorSentinelTokens->container),
46 /// HdDataSourceLocator(
47 /// "foo", "bar", "mySource")}.
48 ///
49 TF_DECLARE_PUBLIC_TOKENS(HdDataSourceLocatorSentinelTokens, HD_API,
51 
52 /// \class HdDataSourceLocator
53 ///
54 /// Represents an object that can identify the location of a data source.
55 /// Data Source Locators are meant to be short lists of tokens that, taken
56 /// together, can represent the location of a given data source.
57 ///
59 {
60 public:
61 
62  /// Returns a common empty locator.
63  ///
64  /// This is an often needed locator and is quicker to get this way rather
65  /// than creating your own empty one.
66  HD_API
67  static const HdDataSourceLocator &EmptyLocator();
68 
69  /// Creates an empty locator.
70  ///
71  /// If all you need is an empty locator, see EmptyLocator().
72  ///
73  HD_API
75 
76  /// The following constructors take a number of tokens and build a locator
77  /// with the apporpriate number of tokens in the given order.
78  ///
79  /// These are convenience constructors for commonly used patterns. Note
80  /// that we generally expect a very small number of entities in a locator,
81  /// which is why we haven't gone with a more general N-way solution.
82  ///
83  HD_API
84  explicit HdDataSourceLocator(const TfToken &t1);
85  HD_API
86  HdDataSourceLocator(const TfToken &t1, const TfToken &t2);
87  HD_API
88  HdDataSourceLocator(const TfToken &t1, const TfToken &t2,
89  const TfToken &t3);
90  HD_API
91  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
92  const TfToken &t4);
93  HD_API
94  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
95  const TfToken &t4, const TfToken &t5);
96  HD_API
97  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
98  const TfToken &t4, const TfToken &t5,
99  const TfToken &t6);
100 
101  /// Builds a data source locator from the \p tokens array of the given
102  /// \p count.
103  ///
104  HD_API
105  HdDataSourceLocator(size_t count, const TfToken *tokens);
106 
107  /// Copy constructor
108  HdDataSourceLocator(const HdDataSourceLocator &rhs) = default;
109 
110  /// Returns the number of elements (tokens) in this data source.
111  HD_API
112  size_t GetElementCount() const;
113 
114  /// Returns the element (token) at index \p i.
115  ///
116  /// If \p i is out of bounds, the behavior is undefined.
117  ///
118  HD_API
119  const TfToken &GetElement(size_t i) const;
120 
121  /// Returns the first element, or empty token if none.
122  HD_API
123  const TfToken &GetFirstElement() const;
124 
125  /// Returns the last element, or empty token if none.
126  HD_API
127  const TfToken &GetLastElement() const;
128 
129  /// Returns a copy of this data source locator with the last element
130  /// replaced by the one given by \p name. If this data source locator is
131  /// empty an identical copy is returned.
132  ///
133  HD_API
134  HdDataSourceLocator ReplaceLastElement(const TfToken &name) const;
135 
136  /// Returns a copy of this data source locator with the last element
137  /// removed.
138  ///
139  HD_API
140  HdDataSourceLocator RemoveLastElement() const;
141 
142  /// Returns a copy of this data source locator with the first element
143  /// removed.
144  ///
145  HD_API
146  HdDataSourceLocator RemoveFirstElement() const;
147 
148  /// Appends \p name to this data source locator.
149  HD_API
150  HdDataSourceLocator Append(const TfToken &name) const;
151 
152  /// Appends all of the elements in \p locator to this data source locator.
153  HD_API
154  HdDataSourceLocator Append(const HdDataSourceLocator &locator) const;
155 
156  /// Prepends \p name to this data source locator.
157  HD_API
158  HdDataSourceLocator Prepend(const TfToken &name) const;
159 
160  /// Prepends all of the elements in \p locator to this data source locator.
161  HD_API
162  HdDataSourceLocator Prepend(const HdDataSourceLocator &locator) const;
163 
164  /// Returns \c true if and only if this data source locator has \p prefix
165  /// as a prefix.
166  /// In particular, returns \c true if this locator is equal to \p prefix.
167  HD_API
168  bool HasPrefix(const HdDataSourceLocator &prefix) const;
169 
170  /// Returns a data source locator that represents the common prefix
171  /// between this data source and \p other.
172  ///
173  HD_API
174  HdDataSourceLocator GetCommonPrefix(const HdDataSourceLocator &other) const;
175 
176  /// Returns a copy of this data source locator with \p oldPrefix replaced
177  /// by \p newPrefix.
178  ///
179  HD_API
180  HdDataSourceLocator ReplacePrefix(
181  const HdDataSourceLocator &oldPrefix,
182  const HdDataSourceLocator &newPrefix) const;
183 
184  /// Returns \c true if and only if either of the two locators is a prefix
185  /// of the other one - in the sense of HasPrefix.
186  /// In particular, it is true if the two locators are equal.
187  ///
188  HD_API
189  bool Intersects(const HdDataSourceLocator &other) const;
190 
191  inline bool operator==(const HdDataSourceLocator &rhs) const {
192  return _tokens == rhs._tokens;
193  }
194 
195  inline bool operator!=(const HdDataSourceLocator &rhs) const {
196  return _tokens != rhs._tokens;
197  }
198 
199  /// Lexicographic order. If y has x as prefix, x < y.
200  HD_API
201  bool operator<(const HdDataSourceLocator &rhs) const;
202 
203  inline bool IsEmpty() const {
204  return _tokens.empty();
205  }
206 
207  /// Returns a string representation of this data source locator with the
208  /// given \p delimiter inserted between each element.
209  ///
210  HD_API
211  std::string GetString(const char *delimiter = "/") const;
212 
213  template <class HashState>
214  friend void TfHashAppend(HashState &h, HdDataSourceLocator const &myObj) {
215  h.AppendContiguous(myObj._tokens.data(), myObj._tokens.size());
216  }
217 
218  inline size_t Hash() const;
219 
220 private:
221  using _TokenVector = TfSmallVector<TfToken, 6>;
222  _TokenVector _tokens;
223 };
224 
225 inline size_t
227 {
228  return TfHash()(*this);
229 }
230 
231 HD_API std::ostream& operator<<(std::ostream& out,
232  const HdDataSourceLocator &self);
233 
234 //-----------------------------------------------------------------------------
235 
236 ///
237 /// \class HdDataSourceLocatorSet
238 ///
239 /// Represents a set of data source locators closed under descendancy. That is,
240 /// if a data source locator x is in the set (that is
241 /// HdDataSourceLocatorSet::Contains returns true), then every data source
242 /// locator y that has x as a prefix is implicitly also assumed to be in the set.
243 ///
244 /// In particular, the data source locator set <x, y> generated by x and y is
245 /// equivalent to (and will be simplified to) just <x> if x is a prefix of y.
246 ///
247 /// Note that HdDataSourceLocatorSet{HdDataSourceLocator()} is the universal
248 /// set containing every data source locator.
249 ///
251 {
252 private:
254 public:
256 
257  /// The empty set.
259 
260  /// The set containing everything.
261  HD_API
262  static const HdDataSourceLocatorSet &UniversalSet();
263 
264  HD_API
266 
267  // Initializer list constructor.
268  HD_API
270  const std::initializer_list<const HdDataSourceLocator> &l);
271 
272  /// Copy Ctor
273  HdDataSourceLocatorSet(const HdDataSourceLocatorSet &rhs) = default;
274 
275  /// Move Ctor.
277 
278  /// Move assignment operator.
280 
281  /// Copy assignment operator.
283  = default;
284 
285  HD_API
286  void insert(const HdDataSourceLocator &locator);
287 
288  /// Changes this set to be the union of this set and the given set.
289  HD_API
290  void insert(const HdDataSourceLocatorSet &locatorSet);
291 
292  /// Changes this set to be the union of this set and the given set.
293  HD_API
294  void insert(HdDataSourceLocatorSet &&locatorSet);
295 
296  /// append() is semantically equivalent to insert(), but works much faster
297  /// if \p locator would be added to the end of the set, lexicographically.
298  HD_API
299  void append(const HdDataSourceLocator &locator);
300 
301  bool operator==(const HdDataSourceLocatorSet &rhs) const {
302  return _locators == rhs._locators;
303  }
304 
305  bool operator!=(const HdDataSourceLocatorSet &rhs) const {
306  return !(*this == rhs);
307  }
308 
309  /// Iterates through minimal, lexicographically sorted list of
310  /// data source locators generating this set.
311  HD_API
312  const_iterator begin() const;
313  HD_API
314  const_iterator end() const;
315 
316  /// True if and only if locator or any of its descendants is
317  /// in the set (closed under descendancy).
318  ///
319  /// In other words, true if and only if there is a generator of this
320  /// set that intersects the given locator in the sense of
321  /// HdDataSourceLocator::Intersects.
322  HD_API
323  bool Intersects(const HdDataSourceLocator &locator) const;
324 
325  /// True if and only if the two sets (closed under descendancy) intersect.
326  ///
327  /// In other words, true if and only if there is a generator x in this
328  /// set and a generator y in the given set such that x and y intersect
329  /// in the sense of HdDataSourceLocator::Intersects. That is, one of the
330  /// two sets contains a prefix of the other set.
331  HD_API
332  bool Intersects(const HdDataSourceLocatorSet &locatorSet) const;
333 
334  /// True if and only if this set contains no data source locator.
335  HD_API
336  bool IsEmpty() const;
337 
338  /// True if the set (closed under descendancy) contains the given
339  /// locator.
340  ///
341  /// In other words, a prefix of the locator is a generator of
342  /// the set in the sense of HdDataSourceLocator::HasPrefix.
343  HD_API
344  bool Contains(const HdDataSourceLocator &locator) const;
345 
346  /// Returns a lexicographically sorted locator set wherein locators in this
347  /// set that have \p oldPrefix as a prefix use \p newPrefix instead. The
348  /// returned set is closed under descendancy and may have equal or fewer
349  /// data source locators as a result.
350  HD_API
352  const HdDataSourceLocator &oldPrefix,
353  const HdDataSourceLocator &newPrefix) const;
354 
355  class IntersectionIterator;
356  class IntersectionView;
357 
358  /// Returns intersection with a locator as a range-like object so that it
359  /// can be used in a for-loop.
360  ///
361  /// Every element in the intersection has locator as a prefix.
362  ///
363  /// Examples:
364  /// Intersection of { primvars:color } with primvars is
365  /// { primvars:color }.
366  /// Intersection of { primvars:color } with primvars:color:interpolation is
367  /// { primvars:color:interpolation }.
368  ///
369  HD_API
370  IntersectionView Intersection(const HdDataSourceLocator &locator) const;
371 
372 private:
373  // Sort and uniquify it.
374  void _Normalize();
375 
376  void _InsertAndDeleteSuffixes(_Locators::iterator *position,
377  const HdDataSourceLocator &locator);
378 
379  const_iterator _FirstIntersection(const HdDataSourceLocator &locator) const;
380 
381  // Lexicographically sorted minimal list of locators generating
382  // the set.
383  _Locators _locators;
384 };
385 
387 {
388 public:
389  using iterator_category = std::forward_iterator_tag;
392  using pointer = value_type*;
393  using difference_type = std::ptrdiff_t;
394 
396  : _isFirst(false)
397  {
398  }
399 
400  IntersectionIterator(const bool isFirst,
401  const const_iterator &iterator,
402  const const_iterator &end,
403  const HdDataSourceLocator &locator)
404  : _isFirst(isFirst)
405  , _iterator(iterator)
406  , _end(end)
407  , _locator(locator)
408  {
409  }
410 
411  HD_API
412  const HdDataSourceLocator &operator*() const;
413 
415  {
416  return std::addressof(**this);
417  }
418 
419  HD_API
421 
422  HD_API
424 
425  bool operator==(const IntersectionIterator &other) const noexcept
426  {
427  return _iterator == other._iterator;
428  }
429 
430  bool operator!=(const IntersectionIterator &other) const noexcept
431  {
432  return _iterator != other._iterator;
433  }
434 
435 private:
436  bool _isFirst;
437  const_iterator _iterator;
438  const_iterator _end;
439  HdDataSourceLocator _locator;
440 };
441 
443 {
444 public:
446  const IntersectionIterator &end)
447  : _begin(begin)
448  , _end(end)
449  {
450  }
451 
452  const IntersectionIterator &begin() const { return _begin; }
453 
454  const IntersectionIterator &end() const { return _end; }
455 
456 private:
457  const IntersectionIterator _begin;
458  const IntersectionIterator _end;
459 };
460 
461 HD_API std::ostream& operator<<(std::ostream& out,
462  const HdDataSourceLocatorSet &self);
463 
465 
466 #endif // PXR_IMAGING_HD_DATASOURCELOCATOR_H
HD_API bool Intersects(const HdDataSourceLocator &other) const
const IntersectionIterator & end() const
friend void TfHashAppend(HashState &h, HdDataSourceLocator const &myObj)
HD_API const HdDataSourceLocator & operator*() const
bool operator==(const HdDataSourceLocator &rhs) const
HD_API HdDataSourceLocator Append(const TfToken &name) const
Appends name to this data source locator.
#define HD_DATA_SOURCE_LOCATOR_SENTINEL_TOKENS
HD_API bool Intersects(const HdDataSourceLocator &locator) const
HdDataSourceLocatorSet()
The empty set.
HD_API HdDataSourceLocator ReplacePrefix(const HdDataSourceLocator &oldPrefix, const HdDataSourceLocator &newPrefix) const
TF_DECLARE_PUBLIC_TOKENS(HdDataSourceLocatorSentinelTokens, HD_API, HD_DATA_SOURCE_LOCATOR_SENTINEL_TOKENS)
size_t Hash() const
HD_API const TfToken & GetElement(size_t i) const
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
HD_API const TfToken & GetFirstElement() const
Returns the first element, or empty token if none.
HD_API std::string GetString(const char *delimiter="/") const
IntersectionIterator(const bool isFirst, const const_iterator &iterator, const const_iterator &end, const HdDataSourceLocator &locator)
typename _Locators::const_iterator const_iterator
HD_API bool IsEmpty() const
True if and only if this set contains no data source locator.
#define HD_API
Definition: api.h:23
size_type size() const
Definition: smallVector.h:596
bool empty() const
Definition: smallVector.h:608
HD_API bool Contains(const HdDataSourceLocator &locator) const
bool operator!=(const HdDataSourceLocator &rhs) const
HD_API IntersectionView Intersection(const HdDataSourceLocator &locator) const
HD_API void append(const HdDataSourceLocator &locator)
HdDataSourceLocatorSet & operator=(HdDataSourceLocatorSet &&rhs)=default
Move assignment operator.
Definition: hash.h:472
HD_API const TfToken & GetLastElement() const
Returns the last element, or empty token if none.
HD_API HdDataSourceLocator RemoveLastElement() const
Definition: token.h:70
bool operator==(const IntersectionIterator &other) const noexcept
HD_API HdDataSourceLocatorSet ReplacePrefix(const HdDataSourceLocator &oldPrefix, const HdDataSourceLocator &newPrefix) const
GLuint GLuint end
Definition: glcorearb.h:475
HD_API std::ostream & operator<<(std::ostream &out, const HdDataSourceLocator &self)
HD_API HdDataSourceLocator Prepend(const TfToken &name) const
Prepends name to this data source locator.
HD_API IntersectionIterator & operator++()
IntersectionView(const IntersectionIterator &begin, const IntersectionIterator &end)
static HD_API const HdDataSourceLocatorSet & UniversalSet()
The set containing everything.
const HdDataSourceLocator * operator->() const
GLuint const GLchar * name
Definition: glcorearb.h:786
HD_API bool HasPrefix(const HdDataSourceLocator &prefix) const
HD_API const_iterator begin() const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
HD_API bool operator<(const HdDataSourceLocator &rhs) const
Lexicographic order. If y has x as prefix, x < y.
HD_API void insert(const HdDataSourceLocator &locator)
HD_API const_iterator end() const
HD_API HdDataSourceLocator ReplaceLastElement(const TfToken &name) const
bool operator!=(const IntersectionIterator &other) const noexcept
SIM_API const UT_StringHolder position
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
HD_API HdDataSourceLocator RemoveFirstElement() const
bool operator!=(const HdDataSourceLocatorSet &rhs) const
static HD_API const HdDataSourceLocator & EmptyLocator()
bool operator==(const HdDataSourceLocatorSet &rhs) const
HD_API HdDataSourceLocator()
const HdDataSourceLocator * const_iterator
Definition: smallVector.h:180
HD_API HdDataSourceLocator GetCommonPrefix(const HdDataSourceLocator &other) const
const IntersectionIterator & begin() const
GLint GLsizei count
Definition: glcorearb.h:405
HD_API size_t GetElementCount() const
Returns the number of elements (tokens) in this data source.
value_type * data()
Definition: smallVector.h:735