HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_PackedFolders.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GU_PackedFolders.h (GU Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GU_PackedFolders__
12 #define __GU_PackedFolders__
13 
14 #include "GU_API.h"
15 #include "GU_DetailHandle.h"
16 #include "GU_PrimPacked.h"
17 #include <UT/UT_ArrayStringMap.h>
18 #include <UT/UT_ArrayStringSet.h>
19 #include <UT/UT_PathPattern.h>
20 #include <UT/UT_StringHolder.h>
21 #include <UT/UT_StringMap.h>
22 #include <variant>
23 
24 class GU_PackedFolders;
25 
26 /// Read-Only Packed Folder Structure
28 {
29 public:
30  /// Class representing a file in the file map
31  class FileInfo
32  {
33  public:
34 
35  /// Path that this file represents
36  const UT_StringHolder &path() const { return myPath; };
37 
38  /// The parent can be in one of three states
39  /// @{
40  bool isParentEmpty() const
41  {
42  return std::holds_alternative<std::monostate>(myParentPrim);
43  }
44  bool isParentPrim() const
45  {
46  return std::holds_alternative<const GU_PrimPacked *>(myParentPrim);
47  }
48  bool isParentRange() const
49  {
50  return std::holds_alternative<GA_Range>(myParentPrim);
51  }
52  /// @}
53 
54  /// Obtain parent as a GU_PrimPacked*, throws if !isParentPrim()
55  /// @{
56  const GU_PrimPacked *parentPrim() const
57  {
58  return std::get<const GU_PrimPacked *>(myParentPrim);
59  }
60  /// @}
61 
62  /// Get parent as a packed primitive, returns nullptr if not a prim
63  /// @{
65  {
66  if (!isParentPrim())
67  return nullptr;
68  return parentPrim();
69  }
70  /// @}
71 
72  /// Get parent as a GA_Range, throws if !isParentRange()
73  /// @{
74  const GA_Range &parentRange() const
75  {
76  return std::get<GA_Range>(myParentPrim);
77  }
78  /// @}
79 
80  /// Return true if parent is a packed primitive and has treatasfolder
81  /// intrinsic enabled
82  bool treatAsFolder() const;
83 
84  /// Return true if we're the root or treatAsFolder()
85  bool isFolder() const
86  {
87  return (myPath == "/" || treatAsFolder());
88  }
89 
90  /// Accessor to GU_DetailHandle of file contents
91  /// @{
92  const GU_ConstDetailHandle &primGdh() const { return myPrimGdh; }
93  /// @}
94 
95  /// Flag accessors
96  /// @{
97  bool isExisting() const { return myExisting; }
98  void setExisting(bool f) { myExisting = f; }
99 
100  bool isModified() const { return myModified; }
101  void setModified(bool f) { myModified = f; }
102 
103  bool isTouched() const { return myTouched; }
104  void setTouched(bool f) { myTouched = f; }
105 
106  bool isCleared() const { return myCleared; }
107  void setCleared(bool f) { myCleared = f; }
108 
109  bool isVisible() const { return myVisible; }
110  void setVisible(bool f) { myVisible = f; }
111  /// @}
112 
113  private:
114  friend class GU_PackedFoldersRO;
115 
116  UT_StringHolder myPath;
117 
118  // myParentPrim is initially monostate.
119  // When myParent is a GU_PrimPacked*/GA_Range, these are primitives
120  // inside its parent's FileInfo::myPrimGdh.
121  std::variant<std::monostate, const GU_PrimPacked *, GA_Range> myParentPrim;
122 
123  // Geometry contents of this file
124  GU_ConstDetailHandle myPrimGdh;
125 
126  bool myExisting = false;
127  bool myModified = false;
128  bool myTouched = false;
129  bool myCleared = false;
130  bool myVisible = true;
131  };
132 
133  /// Construct a folder structure with its own detail
135 
136  /// Construct and build the map over the given detail, holding references
137  /// to it
139  {
140  replaceDetail(d);
141  }
142 
143  ~GU_PackedFoldersRO() = default;
144 
145  /// Copy geometry and hierarchy from another GU_PackedFoldersRO
146  /// @{
149  {
150  *this = src;
151  }
153  /// @}
154 
155  /// Rebuild file map over the given detail, holding references to it
156  void replaceDetail(const GU_DetailHandle &d);
157 
158  /// Check if file at given path is a folder; returns false if file does not
159  /// exist
160  bool isFolder(const UT_StringRef &path) const;
161 
162  /// Get file access for read; returns nullptr if file does not exist
164 
165  /// Fill array with the children of this file at path, if it exists
167  const UT_StringRef &path) const;
168 
169  /// Fill array with files which path the given apex syntax pattern; returns
170  /// false on bad pattern_str
171  /// @param sorted Sorts the output list by file path. If disabled, the list
172  /// is in an arbitrary order.
173  bool findFilesByPattern(
175  const UT_StringRef &pattern_str,
176  bool sorted,
177  UT_StringHolder &error) const;
178 
179  /// Verifies packed primitive implementation pointers. Only does something
180  /// on Windows debug builds.
181  bool verify() const;
182 
183  /// Returns a string representing the topology of the whole
185 
186  /// Returns a string representing the topology of the whole folder structure
187  /// but without actually building the GU_PackedFolders.
188  static UT_StringHolder getTopoFormat(const GU_ConstDetailHandle &root_h);
189 
190 private:
191  FileInfo &rootFileInfo();
192  const FileInfo &rootFileInfo() const;
193 
194  /// Rebuild the file map from myDetail if it was changed externally.
195  void rebuildMap(const GU_ConstDetailHandle &detail);
196 
197  static void rebuildMap( const GU_ConstDetailHandle &detail,
198  UT_ArrayStringMap<FileInfo> &file_map, bool create_details);
199 
200 private:
201  UT_ArrayStringMap<FileInfo> myFileMap;
202 
203  friend GU_PackedFolders;
204 };
205 
206 /// Packed Folder Structure
208 {
209 public:
210  /// Class representing a file in the file map
211  class FileInfo
212  {
213  public:
214 
215  /// Path that this file represents
216  const UT_StringHolder &path() const { return myPath; };
217 
218  /// The parent can be in one of three states
219  /// @{
220  bool isParentEmpty() const
221  {
222  return std::holds_alternative<std::monostate>(myParentPrim);
223  }
224  bool isParentPrim() const
225  {
226  return std::holds_alternative<GU_PrimPacked *>(myParentPrim);
227  }
228  bool isParentRange() const
229  {
230  return std::holds_alternative<GA_Range>(myParentPrim);
231  }
232  /// @}
233 
234  /// Obtain parent as a GU_PrimPacked*, throws if !isParentPrim()
235  /// @{
237  {
238  return std::get<GU_PrimPacked *>(myParentPrim);
239  }
240  const GU_PrimPacked *parentPrim() const
241  {
242  return std::get<GU_PrimPacked *>(myParentPrim);
243  }
244  /// @}
245 
246  /// Get parent as a packed primitive, returns nullptr if not a prim
247  /// @{
249  {
250  auto *pp_prim = std::get_if<GU_PrimPacked *>(&myParentPrim);
251  return pp_prim ? *pp_prim : nullptr;
252  }
254  {
255  auto *pp_prim = std::get_if<GU_PrimPacked *>(&myParentPrim);
256  return pp_prim ? *pp_prim : nullptr;
257  }
258  /// @}
259 
260  /// Get parent as a GA_Range, throws if !isParentRange()
261  /// @{
263  {
264  return std::get<GA_Range>(myParentPrim);
265  }
266  const GA_Range &parentRange() const
267  {
268  return std::get<GA_Range>(myParentPrim);
269  }
270  /// @}
271 
272  /// Return true if parent is a packed primitive and has treatasfolder
273  /// intrinsic enabled
274  bool treatAsFolder() const
275  {
276  const GU_PrimPacked *prim = getIfParentPrim();
277  return prim && GU_PackedFolders::treatAsFolder(prim);
278  }
279 
280  /// Return true if we're the root or treatAsFolder()
281  bool isFolder() const
282  {
283  return myPath == "/" || treatAsFolder();
284  }
285 
286  /// Safe accessors to GU_ConstDetailHandle/GU_DetailHandle of file contents
287  /// @{
289  {
290  return primGdh().castAwayConst();
291  }
292 
293 
295  {
296  if (myPrimGdh.isValid())
297  {
298  return myPrimGdh;
299  }
300 
301  GU_DetailHandle new_gdh;
302  new_gdh.allocateAndSet(new GU_Detail);
303  if (getIfParentPrim())
304  {
305  parentPrim()->unpack(*new_gdh.gdpNC());
306  }
307 
308  myPrimGdh = new_gdh;
309  return myPrimGdh;
310  }
311 
312  void setPrimGdh(const GU_ConstDetailHandle &prim_gdh) { myPrimGdh = prim_gdh; }
313  /// @}
314 
315  /// Flag accessors
316  /// @{
317  bool isExisting() const { return myExisting; }
318  void setExisting(bool f) { myExisting = f; }
319 
320  bool isModified() const { return myModified; }
321  void setModified(bool f) { myModified = f; }
322 
323  bool isTouched() const { return myTouched; }
324  void setTouched(bool f) { myTouched = f; }
325 
326  bool isCleared() const { return myCleared; }
327  void setCleared(bool f) { myCleared = f; }
328 
329  bool isVisible() const { return myVisible; }
330  void setVisible(bool f) { myVisible = f; }
331  /// @}
332 
333  private:
334  friend class GU_PackedFolders;
335 
336  UT_StringHolder myPath;
337 
338  // myParentPrim is initially monostate.
339  // When myParent is a GU_PrimPacked*/GA_Range, these are primitives
340  // inside its parent's FileInfo::myPrimGdh.
341  std::variant<std::monostate, GU_PrimPacked *, GA_Range> myParentPrim;
342 
343  // Geometry contents of this file
344  mutable GU_ConstDetailHandle myPrimGdh;
345 
346  bool myExisting = false;
347  bool myModified = false;
348  bool myTouched = false;
349  bool myCleared = false;
350  bool myVisible = true;
351  };
352 
353  /// Construct a folder structure with its own detail
355 
356  /// Construct and build the map over the given detail, holding references
357  /// to it
358  explicit GU_PackedFolders(GU_DetailHandle &d, bool reuse_detail_ids=false);
359 
360  ~GU_PackedFolders() = default;
361 
362  /// Copy geometry and hierarchy from another GU_PackedFolders
363  /// @{
365  : GU_PackedFolders()
366  {
367  *this = src;
368  }
370  /// @}
371 
372  /// Get and set treatasfolder intrinsic on a packed prim
373  static bool treatAsFolder(const GU_PrimPacked *pack);
374  static void setTreatAsFolder(GU_PrimPacked *pack, bool b);
375 
376  /// Return whether the given primitive is in _3d_hidden_primitives
377  static bool isPrimVisible(const GA_Primitive *prim);
378 
379  /// Path and name processing functions
380  /// @{
383  static void splitFileName(const UT_StringRef &label, UT_WorkBuffer &name,
385  /// @}
386 
387  /// Return packed prim if the detail is a single, packed object; return
388  /// null if not
389  static const GU_PrimPacked *getPackedFromDetail(const GU_Detail *gdp);
390 
391  /// Helper method to set the properties on an existing file
392  bool setFileProperties(const UT_StringRef &path, bool treat_as_folder, bool visible);
393 
394  /// Rebuild file map over the given detail, holding references to it
396 
397  /// Update the chain of packed primitives up the path to the root detail
398  void updatePath(const UT_StringRef &path_str);
399 
400  /// Build a path of folders if it does not exist already.
401  /// Returns true if successful; fails if a file in path_str exists and is
402  /// not a folder
403  bool buildPath(const UT_StringRef &path_str);
404 
405  /// Insert/replace a file at the given path, creating the path if it does
406  /// not exist. If pack is true, pack d before adding to the folder.
407  /// If is_folder is true, set the treatasfolder intrinsic on the inserted
408  /// file.
409  /// Returns true if successful; fails if it can't create the path to the
410  /// file
411  bool insert(
412  const UT_StringRef &path,
413  const GU_ConstDetailHandle &d,
414  bool pack = true,
415  bool is_folder = false,
416  bool is_visible = true);
417 
418  /// Remove a file or folder at the given path.
419  /// Returns true if successful; fails if the given path is the root "/" or
420  /// doesn't exist.
421  bool remove(const UT_StringRef &path_str);
422 
423  /// Set flags to true on a given file and if desired, its children
424  void setFlags(
425  const UT_StringRef &path,
426  bool existing,
427  bool modified,
428  bool touched,
429  bool and_children = false);
430 
431  /// Clear flags to false on a given file and if desired, its children
432  void clearFlags(
433  const UT_StringRef &path,
434  bool existing,
435  bool modified,
436  bool touched,
437  bool and_children = false);
438 
439  /// Sets touch flag on a given file & its children if and_children is true
440  void touch(const UT_StringRef &path, bool and_children = false);
441 
442  /// Mark all folders in the path given as touched
443  void touchFolders(const UT_StringRef &path_str);
444 
445  /// Removes stale files which are flagged as untouched.
446  /// Files flagged existing if found by replaceDetail()/rebuildMap() are
447  /// protected. If backup is provided, files which are untouched, modified,
448  /// and existing will be replaced by the copy in backup. Files are marked
449  /// modified if created/replaced by insert().
450  void removeStale(const GU_PackedFolders *backup = nullptr);
451 
452  /// Check if file at given path is a folder; returns false if file does not
453  /// exist
454  bool isFolder(const UT_StringRef &path) const;
455 
456  /// Get file access for read; returns nullptr if file does not exist
458 
459  /// Fill array with the children of this file at path, if it exists
461  const UT_StringRef &path) const;
462 
463  /// Fill array with files which path the given apex syntax pattern; returns
464  /// false on bad pattern_str
465  /// @param sorted Sorts the output list by file path. If disabled, the list
466  /// is in an arbitrary order.
467  bool findFilesByPattern(
469  const UT_StringRef &pattern_str,
470  bool sorted,
471  UT_StringHolder &error) const;
472 
473  /// Verifies packed primitive implementation pointers. Only does something
474  /// on Windows debug builds.
475  bool verify() const;
476 
477  /// Returns a string representing the topology of the whole
479 
480 private:
481  FileInfo &rootFileInfo();
482  const FileInfo &rootFileInfo() const;
483 
484  /// Rebuild the file map from myDetail if it was changed externally.
485  /// It will clear children of the given path before rebuilding.
486  /// If path does not exist in the map, it will fail silently.
487  /// If mark_existing, myExisting flag will be set on files.
488  void rebuildMap(GU_DetailHandle *detail, const UT_StringRef &path,
489  bool mark_existing = true, bool reuse_detail_ids=false);
490 
491 private:
492  UT_ArrayStringMap<FileInfo> myFileMap;
493 };
494 
496 bool
498 {
499  const GU_PrimPacked *prim = getIfParentPrim();
500  return prim && GU_PackedFolders::treatAsFolder(prim);
501 }
502 
503 namespace UT
504 {
505 template <typename T>
506 struct DefaultClearer;
507 
508 template <>
510 {
511  static void clear(GU_PackedFoldersRO::FileInfo &v) { v.setCleared(true); }
513  {
514  return v.isCleared();
515  }
517  {
518  new ((void *)p) GU_PackedFoldersRO::FileInfo();
519  }
520  static const bool clearNeedsDestruction = true;
521 };
522 
523 template <>
525 {
526  static void clear(GU_PackedFolders::FileInfo &v) { v.setCleared(true); }
528  {
529  return v.isCleared();
530  }
532  {
533  new ((void *)p) GU_PackedFolders::FileInfo();
534  }
535  static const bool clearNeedsDestruction = true;
536 };
537 } // namespace UT
538 
539 #endif
void findChildren(UT_Array< const GU_PackedFolders::FileInfo * > &out, const UT_StringRef &path) const
Fill array with the children of this file at path, if it exists.
bool isFolder(const UT_StringRef &path) const
static bool treatAsFolder(const GU_PrimPacked *pack)
Get and set treatasfolder intrinsic on a packed prim.
static void setTreatAsFolder(GU_PrimPacked *pack, bool b)
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
GU_PackedFoldersRO(const GU_PackedFoldersRO &src)
const GU_ConstDetailHandle & primGdh() const
~GU_PackedFolders()=default
const GLdouble * v
Definition: glcorearb.h:837
UT_StringHolder getTopoFormat() const
Returns a string representing the topology of the whole.
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
GU_PrimPacked * getIfParentPrim()
const GU_PrimPacked * getIfParentPrim() const
void replaceDetail(const GU_DetailHandle &d)
Rebuild file map over the given detail, holding references to it.
const GA_Range & parentRange() const
GU_PackedFolders(const GU_PackedFolders &src)
static void clear(GU_PackedFolders::FileInfo &v)
Read-Only Packed Folder Structure.
void updatePath(const UT_StringRef &path_str)
Update the chain of packed primitives up the path to the root detail.
UT_StringHolder getTopoFormat() const
Returns a string representing the topology of the whole.
void removeStale(const GU_PackedFolders *backup=nullptr)
bool buildPath(const UT_StringRef &path_str)
OIIO_FORCEINLINE vbool4 insert(const vbool4 &a, bool val)
Helper: substitute val for a[i].
Definition: simd.h:3436
static bool isPrimVisible(const GA_Primitive *prim)
Return whether the given primitive is in _3d_hidden_primitives.
Class representing a file in the file map.
const UT_StringHolder & path() const
Path that this file represents.
bool setFileProperties(const UT_StringRef &path, bool treat_as_folder, bool visible)
Helper method to set the properties on an existing file.
void setPrimGdh(const GU_ConstDetailHandle &prim_gdh)
static void clearConstruct(GU_PackedFoldersRO::FileInfo *p)
A range of elements in an index-map.
Definition: GA_Range.h:42
< returns > If no error
Definition: snippets.dox:2
static void splitFileName(const UT_StringRef &label, UT_WorkBuffer &name, UT_WorkBuffer &type)
void allocateAndSet(GU_Detail *gdp, bool own=true)
GLfloat f
Definition: glcorearb.h:1926
const GU_PackedFolders::FileInfo * findFile(const UT_StringRef &path) const
Get file access for read; returns nullptr if file does not exist.
GU_DetailHandle safePrimGdhNC()
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
bool findFilesByPattern(UT_Array< const GU_PackedFolders::FileInfo * > &out, const UT_StringRef &pattern_str, bool sorted, UT_StringHolder &error) const
static void clearConstruct(GU_PackedFolders::FileInfo *p)
GU_ConstDetailHandle primGdh() const
Packed Folder Structure.
bool findFilesByPattern(UT_Array< const GU_PackedFoldersRO::FileInfo * > &out, const UT_StringRef &pattern_str, bool sorted, UT_StringHolder &error) const
void touch(const UT_StringRef &path, bool and_children=false)
Sets touch flag on a given file & its children if and_children is true.
const UT_StringHolder & path() const
Path that this file represents.
static void clear(GU_PackedFoldersRO::FileInfo &v)
void replaceDetail(GU_DetailHandle &d)
Rebuild file map over the given detail, holding references to it.
#define GU_API
Definition: GU_API.h:14
GLuint const GLchar * name
Definition: glcorearb.h:786
void setFlags(const UT_StringRef &path, bool existing, bool modified, bool touched, bool and_children=false)
Set flags to true on a given file and if desired, its children.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
bool isFolder() const
Return true if we're the root or treatAsFolder()
GU_Detail * gdpNC()
static const GU_PrimPacked * getPackedFromDetail(const GU_Detail *gdp)
Class representing a file in the file map.
const GA_Range & parentRange() const
GU_PackedFoldersRO()
Construct a folder structure with its own detail.
const GU_PackedFoldersRO::FileInfo * findFile(const UT_StringRef &path) const
Get file access for read; returns nullptr if file does not exist.
static void splitFirstDirectory(UT_WorkBuffer &path, UT_WorkBuffer &out)
GU_PrimPacked * parentPrim()
bool verify() const
const GU_PrimPacked * parentPrim() const
LeafData & operator=(const LeafData &)=delete
void findChildren(UT_Array< const GU_PackedFoldersRO::FileInfo * > &out, const UT_StringRef &path) const
Fill array with the children of this file at path, if it exists.
static void splitLastDirectory(UT_WorkBuffer &path, UT_WorkBuffer &out)
const GU_PrimPacked * getIfParentPrim() const
GU_PackedFoldersRO(const GU_DetailHandle &d)
const GU_PrimPacked * parentPrim() const
~GU_PackedFoldersRO()=default
bool isFolder() const
Return true if we're the root or treatAsFolder()
bool verify() const
void clearFlags(const UT_StringRef &path, bool existing, bool modified, bool touched, bool and_children=false)
Clear flags to false on a given file and if desired, its children.
GU_PackedFolders()
Construct a folder structure with its own detail.
type
Definition: core.h:1059
void touchFolders(const UT_StringRef &path_str)
Mark all folders in the path given as touched.
static bool isClear(const GU_PackedFolders::FileInfo &v)
bool isFolder(const UT_StringRef &path) const
GLenum src
Definition: glcorearb.h:1793
static bool isClear(const GU_PackedFoldersRO::FileInfo &v)