HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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  /// Destructor
68  ~GABC_IArchive();
69 
70  /// Test validity
71  bool valid() const { return myArchive.valid(); }
72 
73  /// Check to see if the archive has been purged (invalid)
74  bool purged() const { return myPurged; }
75 
76  /// Error (set on creation)
77  const std::string &error() const { return myError; }
78 
79  /// Access the filename
80  const std::string &filename() const { return myFilename; }
81 
82  /// Get the root object
83  GABC_IObject getTop() const;
84 
85  /// Access to the underlying archive
86  const IArchive &archive() const { return myArchive; }
87 
88  bool isOgawa() const { return myIsOgawa; }
89 
90  /// Purge all objects references
91  void purgeObjects();
92 
93  /// Close and reopen the archive with the given number of file streams
94  /// (-1 is to use the default)
95  void reopenStream(int num_ogawa_streams = -1);
96 
97  /// @{
98  /// @private
99  /// Called by GABC_IObject to resolve the object
100  void resolveObject(GABC_IObject &obj);
101 
102  /// Called to maintain references to GABC_IItem objects
103  void reference(GABC_IItem *item);
104  void unreference(GABC_IItem *item);
105  /// @}
106 
107  /// @{
108  /// Reference counting
109  void incref() { myRefCount.add(1); }
110  void decref()
111  {
112  if (!myRefCount.add(-1))
113  {
114  closeAndDelete();
115  }
116  }
117  /// @}
118 
119  /// @{
120  /// Open an archive. Please use GABC_Util::open instead
121  /// This method is @b not thread-safe. You must lock around it.
122  /// @private
123  static GABC_IArchivePtr open(const std::string &filename,
124  int num_ogawa_streams = -1);
125  /// @}
126 
127 private:
128  void openArchive(const std::string &path, 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::string &filename,
135  int num_streams = -1);
136 
137  // At the current time, HDF5 requires a *global* lock across all files.
138  // Wouldn't it be nice if it could have a per-file lock?
139  static UT_Lock *theLock;
140 
141  bool openStream(const std::string &path,
142  int num_streams = -1);
143  void clearStream();
144 
145  SYS_AtomicInt32 myRefCount;
146  std::string myFilename;
147  std::string myError;
148  struct gabc_streamentry
149  {
150  gabc_streamentry()
151  : myReader(nullptr), myStreamBuf(nullptr), myStream(nullptr) {}
152  ~gabc_streamentry()
153  {
154  delete myReader;
155  delete myStreamBuf;
156  delete myStream;
157  }
158  gabc_istream *myReader;
159  gabc_streambuf *myStreamBuf;
160  std::istream *myStream;
161  };
162  UT_Array<gabc_streamentry> myStreams;
163  IArchive myArchive;
164  SetType myObjects;
165  bool myPurged;
166  bool myIsOgawa;
167 };
168 
169 static inline void intrusive_ptr_add_ref(GABC_IArchive *i) { i->incref(); }
170 static inline void intrusive_ptr_release(GABC_IArchive *i) { i->decref(); }
171 
172 /// When running with a thread safe Alembic implementation, the fake lock is
173 /// used (since the underlying library is safe).
175 {
176 public:
180  void unlock() {}
181 };
182 /// The true lock is an implementation of a UT_AutoLock which is used when
183 /// locking internal library structures.
185 {
186 public:
188  : myLock(&(arch.getLock()))
189  {
190  if (myLock)
191  myLock->lock();
192  }
194  : myLock(arch ? &(arch->getLock()) : NULL)
195  {
196  if (myLock)
197  myLock->lock();
198  }
200  {
201  if (myLock)
202  myLock->unlock();
203  }
204  void unlock() { myLock->unlock(); myLock = NULL; }
205 private:
206  UT_Lock *myLock;
207 };
208 
209 #if defined(GABC_ALEMBIC_THREADSAFE)
211 #else
213 #endif
214 
215 }
216 
217 #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:71
const std::string & filename() const
Access the filename.
Definition: GABC_IArchive.h:80
virtual int open(float queuesize)
const IArchive & archive() const
Access to the underlying archive.
Definition: GABC_IArchive.h:86
GABC_AutoLock(const GABC_IArchive &arch)
bool purged() const
Check to see if the archive has been purged (invalid)
Definition: GABC_IArchive.h:74
#define GABC_API
Definition: GABC_API.h:37
const std::string & error() const
Error (set on creation)
Definition: GABC_IArchive.h:77
GABC_AutoFakeLock(const GABC_IArchive &)