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 <variant>
22 
23 /// Read-Only Packed Folder Structure
25 {
26 public:
27  /// Class representing a file in the file map
28  class FileInfo
29  {
30  public:
31 
32  /// Path that this file represents
33  const UT_StringHolder &path() const { return myPath; };
34 
35  /// The parent can be in one of three states
36  /// @{
37  bool isParentEmpty() const
38  {
39  return std::holds_alternative<std::monostate>(myParentPrim);
40  }
41  bool isParentPrim() const
42  {
43  return std::holds_alternative<const GU_PrimPacked *>(myParentPrim);
44  }
45  bool isParentRange() const
46  {
47  return std::holds_alternative<GA_Range>(myParentPrim);
48  }
49  /// @}
50 
51  /// Obtain parent as a GU_PrimPacked*, throws if !isParentPrim()
52  /// @{
53  const GU_PrimPacked *parentPrim() const
54  {
55  return std::get<const GU_PrimPacked *>(myParentPrim);
56  }
57  /// @}
58 
59  /// Get parent as a packed primitive, returns nullptr if not a prim
60  /// @{
62  {
63  if (!isParentPrim())
64  return nullptr;
65  return parentPrim();
66  }
67  /// @}
68 
69  /// Get parent as a GA_Range, throws if !isParentRange()
70  /// @{
71  const GA_Range &parentRange() const
72  {
73  return std::get<GA_Range>(myParentPrim);
74  }
75  /// @}
76 
77  /// Return true if parent is a packed primitive and has treatasfolder
78  /// intrinsic enabled
79  bool treatAsFolder() const;
80 
81  /// Return true if we're the root or treatAsFolder()
82  bool isFolder() const
83  {
84  return (myPath == "/" || treatAsFolder());
85  }
86 
87  /// Accessor to GU_DetailHandle of file contents
88  /// @{
89  const GU_ConstDetailHandle &primGdh() const { return myPrimGdh; }
90  /// @}
91 
92  /// Flag accessors
93  /// @{
94  bool isExisting() const { return myExisting; }
95  void setExisting(bool f) { myExisting = f; }
96 
97  bool isModified() const { return myModified; }
98  void setModified(bool f) { myModified = f; }
99 
100  bool isTouched() const { return myTouched; }
101  void setTouched(bool f) { myTouched = f; }
102 
103  bool isCleared() const { return myCleared; }
104  void setCleared(bool f) { myCleared = f; }
105 
106  bool isVisible() const { return myVisible; }
107  void setVisible(bool f) { myVisible = f; }
108  /// @}
109 
110  private:
111  friend class GU_PackedFoldersRO;
112 
113  UT_StringHolder myPath;
114 
115  // myParentPrim is initially monostate.
116  // When myParent is a GU_PrimPacked*/GA_Range, these are primitives
117  // inside its parent's FileInfo::myPrimGdh.
118  std::variant<std::monostate, const GU_PrimPacked *, GA_Range> myParentPrim;
119 
120  // Geometry contents of this file
121  GU_ConstDetailHandle myPrimGdh;
122 
123  bool myExisting = false;
124  bool myModified = false;
125  bool myTouched = false;
126  bool myCleared = false;
127  bool myVisible = true;
128  };
129 
130  /// Construct a folder structure with its own detail
132 
133  /// Construct and build the map over the given detail, holding references
134  /// to it
136  {
137  replaceDetail(d);
138  }
139 
140  ~GU_PackedFoldersRO() = default;
141 
142  /// Copy geometry and hierarchy from another GU_PackedFoldersRO
143  /// @{
146  {
147  *this = src;
148  }
150  /// @}
151 
152  /// Rebuild file map over the given detail, holding references to it
153  void replaceDetail(const GU_DetailHandle &d);
154 
155  /// Check if file at given path is a folder; returns false if file does not
156  /// exist
157  bool isFolder(const UT_StringRef &path) const;
158 
159  /// Get file access for read; returns nullptr if file does not exist
161 
162  /// Fill array with the children of this file at path, if it exists
164  const UT_StringRef &path) const;
165 
166  /// Fill array with files which path the given apex syntax pattern; returns
167  /// false on bad pattern_str
168  bool findFilesByPattern(
170  const UT_StringRef &pattern_str,
171  UT_StringHolder &error) const;
172 
173  /// Verifies packed primitive implementation pointers. Only does something
174  /// on Windows debug builds.
175  bool verify() const;
176 
177 private:
178  FileInfo &rootFileInfo();
179  const FileInfo &rootFileInfo() const;
180 
181  /// Rebuild the file map from myDetail if it was changed externally.
182  void rebuildMap(const GU_ConstDetailHandle &detail);
183 
184 private:
185  UT_ArrayStringMap<FileInfo> myFileMap;
186 };
187 
188 /// Packed Folder Structure
190 {
191 public:
192  /// Class representing a file in the file map
193  class FileInfo
194  {
195  public:
196 
197  /// Path that this file represents
198  const UT_StringHolder &path() const { return myPath; };
199 
200  /// The parent can be in one of three states
201  /// @{
202  bool isParentEmpty() const
203  {
204  return std::holds_alternative<std::monostate>(myParentPrim);
205  }
206  bool isParentPrim() const
207  {
208  return std::holds_alternative<GU_PrimPacked *>(myParentPrim);
209  }
210  bool isParentRange() const
211  {
212  return std::holds_alternative<GA_Range>(myParentPrim);
213  }
214  /// @}
215 
216  /// Obtain parent as a GU_PrimPacked*, throws if !isParentPrim()
217  /// @{
219  {
220  return std::get<GU_PrimPacked *>(myParentPrim);
221  }
222  const GU_PrimPacked *parentPrim() const
223  {
224  return std::get<GU_PrimPacked *>(myParentPrim);
225  }
226  /// @}
227 
228  /// Get parent as a packed primitive, returns nullptr if not a prim
229  /// @{
231  {
232  auto *pp_prim = std::get_if<GU_PrimPacked *>(&myParentPrim);
233  return pp_prim ? *pp_prim : nullptr;
234  }
236  {
237  auto *pp_prim = std::get_if<GU_PrimPacked *>(&myParentPrim);
238  return pp_prim ? *pp_prim : nullptr;
239  }
240  /// @}
241 
242  /// Get parent as a GA_Range, throws if !isParentRange()
243  /// @{
245  {
246  return std::get<GA_Range>(myParentPrim);
247  }
248  const GA_Range &parentRange() const
249  {
250  return std::get<GA_Range>(myParentPrim);
251  }
252  /// @}
253 
254  /// Return true if parent is a packed primitive and has treatasfolder
255  /// intrinsic enabled
256  bool treatAsFolder() const
257  {
258  const GU_PrimPacked *prim = getIfParentPrim();
259  return prim && GU_PackedFolders::treatAsFolder(prim);
260  }
261 
262  /// Return true if we're the root or treatAsFolder()
263  bool isFolder() const
264  {
265  return myPath == "/" || treatAsFolder();
266  }
267 
268  /// Safe accessors to GU_ConstDetailHandle/GU_DetailHandle of file contents
269  /// @{
271  {
272  return primGdh().castAwayConst();
273  }
274 
276  {
277  if (myPrimGdh.isValid())
278  {
279  return myPrimGdh;
280  }
281 
282  GU_DetailHandle new_gdh;
283  new_gdh.allocateAndSet(new GU_Detail);
284  if (getIfParentPrim())
285  {
286  parentPrim()->unpack(*new_gdh.gdpNC());
287  }
288 
289  myPrimGdh = new_gdh;
290  return myPrimGdh;
291  }
292 
293  void setPrimGdh(const GU_ConstDetailHandle &prim_gdh) { myPrimGdh = prim_gdh; }
294  /// @}
295 
296  /// Flag accessors
297  /// @{
298  bool isExisting() const { return myExisting; }
299  void setExisting(bool f) { myExisting = f; }
300 
301  bool isModified() const { return myModified; }
302  void setModified(bool f) { myModified = f; }
303 
304  bool isTouched() const { return myTouched; }
305  void setTouched(bool f) { myTouched = f; }
306 
307  bool isCleared() const { return myCleared; }
308  void setCleared(bool f) { myCleared = f; }
309 
310  bool isVisible() const { return myVisible; }
311  void setVisible(bool f) { myVisible = f; }
312  /// @}
313 
314  private:
315  friend class GU_PackedFolders;
316 
317  UT_StringHolder myPath;
318 
319  // myParentPrim is initially monostate.
320  // When myParent is a GU_PrimPacked*/GA_Range, these are primitives
321  // inside its parent's FileInfo::myPrimGdh.
322  std::variant<std::monostate, GU_PrimPacked *, GA_Range> myParentPrim;
323 
324  // Geometry contents of this file
325  mutable GU_ConstDetailHandle myPrimGdh;
326 
327  bool myExisting = false;
328  bool myModified = false;
329  bool myTouched = false;
330  bool myCleared = false;
331  bool myVisible = true;
332  };
333 
334  /// Construct a folder structure with its own detail
336 
337  /// Construct and build the map over the given detail, holding references
338  /// to it
340  {
341  replaceDetail(d);
342  }
343 
344  ~GU_PackedFolders() = default;
345 
346  /// Copy geometry and hierarchy from another GU_PackedFolders
347  /// @{
349  : GU_PackedFolders()
350  {
351  *this = src;
352  }
354  /// @}
355 
356  /// Get and set treatasfolder intrinsic on a packed prim
357  static bool treatAsFolder(const GU_PrimPacked *pack);
358  static void setTreatAsFolder(GU_PrimPacked *pack, bool b);
359 
360  /// Return whether the given primitive is in _3d_hidden_primitives
361  static bool isPrimVisible(const GA_Primitive *prim);
362 
363  /// Path and name processing functions
364  /// @{
367  static void splitFileName(const UT_StringRef &label, UT_WorkBuffer &name,
369  /// @}
370 
371  /// Return packed prim if the detail is a single, packed object; return
372  /// null if not
373  static const GU_PrimPacked *getPackedFromDetail(const GU_Detail *gdp);
374 
375  /// Helper method to set the properties on an existing file
376  bool setFileProperties(const UT_StringRef &path, bool treat_as_folder, bool visible);
377 
378  /// Rebuild file map over the given detail, holding references to it
380 
381  /// Update the chain of packed primitives up the path to the root detail
382  void updatePath(const UT_StringRef &path_str);
383 
384  /// Build a path of folders if it does not exist already.
385  /// Returns true if successful; fails if a file in path_str exists and is
386  /// not a folder
387  bool buildPath(const UT_StringRef &path_str);
388 
389  /// Insert/replace a file at the given path, creating the path if it does
390  /// not exist. If pack is true, pack d before adding to the folder.
391  /// If is_folder is true, set the treatasfolder intrinsic on the inserted
392  /// file.
393  /// Returns true if successful; fails if it can't create the path to the
394  /// file
395  bool insert(
396  const UT_StringRef &path,
397  const GU_ConstDetailHandle &d,
398  bool pack = true,
399  bool is_folder = false,
400  bool is_visible = true);
401 
402  /// Remove a file or folder at the given path.
403  /// Returns true if successful; fails if the given path is the root "/" or
404  /// doesn't exist.
405  bool remove(const UT_StringRef &path_str);
406 
407  /// Set flags to true on a given file and if desired, its children
408  void setFlags(
409  const UT_StringRef &path,
410  bool existing,
411  bool modified,
412  bool touched,
413  bool and_children = false);
414 
415  /// Clear flags to false on a given file and if desired, its children
416  void clearFlags(
417  const UT_StringRef &path,
418  bool existing,
419  bool modified,
420  bool touched,
421  bool and_children = false);
422 
423  /// Sets touch flag on a given file & its children if and_children is true
424  void touch(const UT_StringRef &path, bool and_children = false);
425 
426  /// Mark all folders in the path given as touched
427  void touchFolders(const UT_StringRef &path_str);
428 
429  /// Removes stale files which are flagged as untouched.
430  /// Files flagged existing if found by replaceDetail()/rebuildMap() are
431  /// protected. If backup is provided, files which are untouched, modified,
432  /// and existing will be replaced by the copy in backup. Files are marked
433  /// modified if created/replaced by insert().
434  void removeStale(const GU_PackedFolders *backup = nullptr);
435 
436  /// Check if file at given path is a folder; returns false if file does not
437  /// exist
438  bool isFolder(const UT_StringRef &path) const;
439 
440  /// Get file access for read; returns nullptr if file does not exist
442 
443  /// Fill array with the children of this file at path, if it exists
445  const UT_StringRef &path) const;
446 
447  /// Fill array with files which path the given apex syntax pattern; returns
448  /// false on bad pattern_str
449  bool findFilesByPattern(
451  const UT_StringRef &pattern_str,
452  UT_StringHolder &error) const;
453 
454  /// Verifies packed primitive implementation pointers. Only does something
455  /// on Windows debug builds.
456  bool verify() const;
457 
458 private:
459  FileInfo &rootFileInfo();
460  const FileInfo &rootFileInfo() const;
461 
462  /// Rebuild the file map from myDetail if it was changed externally.
463  /// It will clear children of the given path before rebuilding.
464  /// If path does not exist in the map, it will fail silently.
465  /// If mark_existing, myExisting flag will be set on files.
466  void rebuildMap(GU_DetailHandle *detail, const UT_StringRef &path,
467  bool mark_existing = true);
468 
469 private:
470  UT_ArrayStringMap<FileInfo> myFileMap;
471 };
472 
474 bool
476 {
477  const GU_PrimPacked *prim = getIfParentPrim();
478  return prim && GU_PackedFolders::treatAsFolder(prim);
479 }
480 
481 namespace UT
482 {
483 template <typename T>
484 struct DefaultClearer;
485 
486 template <>
488 {
489  static void clear(GU_PackedFoldersRO::FileInfo &v) { v.setCleared(true); }
491  {
492  return v.isCleared();
493  }
495  {
496  new ((void *)p) GU_PackedFoldersRO::FileInfo();
497  }
498  static const bool clearNeedsDestruction = true;
499 };
500 
501 template <>
503 {
504  static void clear(GU_PackedFolders::FileInfo &v) { v.setCleared(true); }
506  {
507  return v.isCleared();
508  }
510  {
511  new ((void *)p) GU_PackedFolders::FileInfo();
512  }
513  static const bool clearNeedsDestruction = true;
514 };
515 } // namespace UT
516 
517 #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
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
GU_PrimPacked * getIfParentPrim()
GU_PackedFolders & operator=(const GU_PackedFolders &src)
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.
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()
GU_PackedFolders(GU_DetailHandle &d)
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
static void clearConstruct(GU_PackedFolders::FileInfo *p)
GU_ConstDetailHandle primGdh() const
Packed Folder Structure.
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
bool findFilesByPattern(UT_Array< const GU_PackedFolders::FileInfo * > &out, const UT_StringRef &pattern_str, UT_StringHolder &error) const
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
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.
GU_PackedFoldersRO & operator=(const GU_PackedFoldersRO &src)
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
bool findFilesByPattern(UT_Array< const GU_PackedFoldersRO::FileInfo * > &out, const UT_StringRef &pattern_str, UT_StringHolder &error) const
GLenum src
Definition: glcorearb.h:1793
static bool isClear(const GU_PackedFoldersRO::FileInfo &v)