HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GABC_IArchive.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) COPYRIGHTYEAR
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  */
27 
28 #ifndef __GABC_IArchive__
29 #define __GABC_IArchive__
30 
31 #include "GABC_API.h"
32 #include "GABC_Include.h"
33 #include "GABC_IObject.h"
34 #include <SYS/SYS_AtomicInt.h>
35 #include <UT/UT_Lock.h>
36 #include <UT/UT_Set.h>
37 #include <UT/UT_IStream.h>
38 #include <FS/FS_Reader.h>
39 #include <FS/FS_IStreamDevice.h>
40 #include <Alembic/Abc/IArchive.h>
41 #include <SYS/SYS_BoostStreams.h>
42 
43 // Change this when Ogawa is supported
44 #if ALEMBIC_LIBRARY_VERSION >= 10200
45  #define GABC_OGAWA 1
46 #endif
47 
48 // If you're using a thread-safe version of Alembic (thread-safe HDF5 or Ogawa
49 // for example), you can set this define.
50 #define GABC_ALEMBIC_THREADSAFE
51 
52 namespace GABC_NAMESPACE
53 {
54 
55 class GABC_IItem;
56 
57 /// Wrapper around an Alembic archive. This provides thread-safe access to
58 /// Alembic data.
60 {
61 public:
66 
67  /// Test validity
68  bool valid() const { return myArchive.valid(); }
69 
70  /// Error (set on creation)
71  const std::string &error() const { return myError; }
72 
73  /// Access the filename
74  const std::vector<std::string> &filenames() const { return myFileNames; }
75 
76  /// Get the root object
77  GABC_IObject getTop() const;
78 
79  /// Access to the underlying archive
80  const IArchive &archive() const { return myArchive; }
81 
82  bool isOgawa() const { return myIsOgawa; }
83 
84  /// Purge all object references
85  void purgeObjects();
86 
87  /// Close and reopen the archive with the given number of file streams
88  /// (-1 is to use the default)
89  void reopenStream(int num_ogawa_streams = -1);
90 
91  /// @{
92  /// @private
93  /// Called by GABC_IObject to resolve the object
94  void resolveObject(GABC_IObject &obj);
95 
96  /// Called to maintain references to GABC_IItem objects
97  void reference(GABC_IItem *item);
98  void unreference(GABC_IItem *item);
99  /// @}
100 
101  /// @{
102  /// Reference counting
103  void incref() { myRefCount.add(1); }
104  void decref()
105  {
106  if (!myRefCount.add(-1))
107  {
108  closeAndDelete();
109  }
110  }
111  /// @}
112 
113  /// @{
114  /// Open an archive. Please use GABC_Util::open instead
115  /// This method is @b not thread-safe. You must lock around it.
116  /// @private
117  static GABC_IArchivePtr open(const std::vector<std::string> &filenames,
118  int num_ogawa_streams = -1);
119  /// @}
120 
121  /// @{
122  /// Generate a single, user-friendly printable string from a list
123  /// of filenames
124  static std::string filenamesToString(const std::vector<std::string> &filenames);
125  /// @}
126 
127 private:
128  void openArchive(const std::vector<std::string> &paths, int num_streams);
129  void closeAndDelete();
130  /// Access to the file lock - required for non-thread safe HDF5
131  UT_Lock &getLock() const { return *theLock; }
132  friend class GABC_AutoLock;
133 
134  GABC_IArchive(const std::vector<std::string> &filenames,
135  int num_streams = -1);
136 
137  /// Destructor
138  ~GABC_IArchive();
139 
140  // At the current time, HDF5 requires a *global* lock across all files.
141  // Wouldn't it be nice if it could have a per-file lock?
142  static UT_Lock *theLock;
143 
144  bool openStream(const std::string &path,
145  int num_streams = -1);
146  void clearStream();
147 
148  SYS_AtomicInt32 myRefCount;
149  std::vector<std::string> myFileNames;
150  std::string myError;
151  struct gabc_streamentry
152  {
153  gabc_streamentry()
154  : myReader(nullptr), myStreamBuf(nullptr), myStream(nullptr) {}
155  ~gabc_streamentry()
156  {
157  delete myReader;
158  delete myStreamBuf;
159  delete myStream;
160  }
161  gabc_istream *myReader;
162  gabc_streambuf *myStreamBuf;
163  std::istream *myStream;
164  };
165  UT_Array<gabc_streamentry> myStreams;
166  IArchive myArchive;
167  SetType myObjects;
168  bool myPurged;
169  bool myIsOgawa;
170 };
171 
172 static inline void intrusive_ptr_add_ref(GABC_IArchive *i) { i->incref(); }
173 static inline void intrusive_ptr_release(GABC_IArchive *i) { i->decref(); }
174 
175 /// When running with a thread safe Alembic implementation, the fake lock is
176 /// used (since the underlying library is safe).
178 {
179 public:
183  void unlock() {}
184 };
185 /// The true lock is an implementation of a UT_AutoLock which is used when
186 /// locking internal library structures.
188 {
189 public:
191  : myLock(&(arch.getLock()))
192  {
193  if (myLock)
194  myLock->lock();
195  }
197  : myLock(arch ? &(arch->getLock()) : NULL)
198  {
199  if (myLock)
200  myLock->lock();
201  }
203  {
204  if (myLock)
205  myLock->unlock();
206  }
207  void unlock() { myLock->unlock(); myLock = NULL; }
208 private:
209  UT_Lock *myLock;
210 };
211 
212 #if defined(GABC_ALEMBIC_THREADSAFE)
214 #else
216 #endif
217 
218 }
219 
220 #endif
FS_IStreamDeviceBuffer gabc_streambuf
Definition: GABC_IArchive.h:63
GABC_AutoFakeLock(const GABC_IArchivePtr &)
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
png_uint_32 i
Definition: png.h:2877
#define GABC_NAMESPACE
Definition: GABC_API.h:42
bios::stream_buffer< FS_IStreamDevice > FS_IStreamDeviceBuffer
GABC_AutoLock(const GABC_IArchivePtr &arch)
bool valid() const
Test validity.
Definition: GABC_IArchive.h:68
virtual int open(float queuesize)
const std::vector< std::string > & filenames() const
Access the filename.
Definition: GABC_IArchive.h:74
const IArchive & archive() const
Access to the underlying archive.
Definition: GABC_IArchive.h:80
GABC_AutoLock(const GABC_IArchive &arch)
#define GABC_API
Definition: GABC_API.h:37
const std::string & error() const
Error (set on creation)
Definition: GABC_IArchive.h:71
GABC_AutoFakeLock(const GABC_IArchive &)