PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 00037 #ifndef INCLUDED_IMF_ATTRIBUTE_H 00038 #define INCLUDED_IMF_ATTRIBUTE_H 00039 00040 //----------------------------------------------------------------------------- 00041 // 00042 // class Attribute 00043 // 00044 //----------------------------------------------------------------------------- 00045 00046 #include "IexBaseExc.h" 00047 #include <ImfIO.h> 00048 #include <ImfXdr.h> 00049 00050 00051 namespace Imf { 00052 00053 00054 class Attribute 00055 { 00056 public: 00057 00058 //--------------------------- 00059 // Constructor and destructor 00060 //--------------------------- 00061 00062 Attribute (); 00063 virtual ~Attribute (); 00064 00065 00066 //------------------------------- 00067 // Get this attribute's type name 00068 //------------------------------- 00069 00070 virtual const char * typeName () const = 0; 00071 00072 00073 //------------------------------ 00074 // Make a copy of this attribute 00075 //------------------------------ 00076 00077 virtual Attribute * copy () const = 0; 00078 00079 00080 //---------------------------------------- 00081 // Type-specific attribute I/O and copying 00082 //---------------------------------------- 00083 00084 virtual void writeValueTo (OStream &os, 00085 int version) const = 0; 00086 00087 virtual void readValueFrom (IStream &is, 00088 int size, 00089 int version) = 0; 00090 00091 virtual void copyValueFrom (const Attribute &other) = 0; 00092 00093 00094 //------------------ 00095 // Attribute factory 00096 //------------------ 00097 00098 static Attribute * newAttribute (const char typeName[]); 00099 00100 00101 //----------------------------------------------------------- 00102 // Test if a given attribute type has already been registered 00103 //----------------------------------------------------------- 00104 00105 static bool knownType (const char typeName[]); 00106 00107 00108 protected: 00109 00110 //-------------------------------------------------- 00111 // Register an attribute type so that newAttribute() 00112 // knows how to make objects of this type. 00113 //-------------------------------------------------- 00114 00115 static void registerAttributeType (const char typeName[], 00116 Attribute *(*newAttribute)()); 00117 00118 //------------------------------------------------------ 00119 // Un-register an attribute type so that newAttribute() 00120 // no longer knows how to make objects of this type (for 00121 // debugging only). 00122 //------------------------------------------------------ 00123 00124 static void unRegisterAttributeType (const char typeName[]); 00125 }; 00126 00127 00128 //------------------------------------------------- 00129 // Class template for attributes of a specific type 00130 //------------------------------------------------- 00131 00132 template <class T> 00133 class TypedAttribute: public Attribute 00134 { 00135 public: 00136 00137 //---------------------------- 00138 // Constructors and destructor 00139 //------------_--------------- 00140 00141 TypedAttribute (); 00142 TypedAttribute (const T &value); 00143 TypedAttribute (const TypedAttribute<T> &other); 00144 virtual ~TypedAttribute (); 00145 00146 00147 //-------------------------------- 00148 // Access to the attribute's value 00149 //-------------------------------- 00150 00151 T & value (); 00152 const T & value () const; 00153 00154 00155 //-------------------------------- 00156 // Get this attribute's type name. 00157 //-------------------------------- 00158 00159 virtual const char * typeName () const; 00160 00161 00162 //--------------------------------------------------------- 00163 // Static version of typeName() 00164 // This function must be specialized for each value type T. 00165 //--------------------------------------------------------- 00166 00167 static const char * staticTypeName (); 00168 00169 00170 //--------------------- 00171 // Make a new attribute 00172 //--------------------- 00173 00174 static Attribute * makeNewAttribute (); 00175 00176 00177 //------------------------------ 00178 // Make a copy of this attribute 00179 //------------------------------ 00180 00181 virtual Attribute * copy () const; 00182 00183 00184 //----------------------------------------------------------------- 00185 // Type-specific attribute I/O and copying. 00186 // Depending on type T, these functions may have to be specialized. 00187 //----------------------------------------------------------------- 00188 00189 virtual void writeValueTo (OStream &os, 00190 int version) const; 00191 00192 virtual void readValueFrom (IStream &is, 00193 int size, 00194 int version); 00195 00196 virtual void copyValueFrom (const Attribute &other); 00197 00198 00199 //------------------------------------------------------------ 00200 // Dynamic casts that throw exceptions instead of returning 0. 00201 //------------------------------------------------------------ 00202 00203 static TypedAttribute * cast (Attribute *attribute); 00204 static const TypedAttribute * cast (const Attribute *attribute); 00205 static TypedAttribute & cast (Attribute &attribute); 00206 static const TypedAttribute & cast (const Attribute &attribute); 00207 00208 00209 //--------------------------------------------------------------- 00210 // Register this attribute type so that Attribute::newAttribute() 00211 // knows how to make objects of this type. 00212 // 00213 // Note that this function is not thread-safe because it modifies 00214 // a global variable in the IlmIlm library. A thread in a multi- 00215 // threaded program may call registerAttributeType() only when no 00216 // other thread is accessing any functions or classes in the 00217 // IlmImf library. 00218 // 00219 //--------------------------------------------------------------- 00220 00221 static void registerAttributeType (); 00222 00223 00224 //----------------------------------------------------- 00225 // Un-register this attribute type (for debugging only) 00226 //----------------------------------------------------- 00227 00228 static void unRegisterAttributeType (); 00229 00230 00231 private: 00232 00233 T _value; 00234 }; 00235 00236 00237 //------------------------------------ 00238 // Implementation of TypedAttribute<T> 00239 //------------------------------------ 00240 00241 template <class T> 00242 TypedAttribute<T>::TypedAttribute (): 00243 Attribute (), 00244 _value (T()) 00245 { 00246 // empty 00247 } 00248 00249 00250 template <class T> 00251 TypedAttribute<T>::TypedAttribute (const T &value): 00252 Attribute (), 00253 _value (value) 00254 { 00255 // empty 00256 } 00257 00258 00259 template <class T> 00260 TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other): 00261 Attribute (other), 00262 _value () 00263 { 00264 copyValueFrom (other); 00265 } 00266 00267 00268 template <class T> 00269 TypedAttribute<T>::~TypedAttribute () 00270 { 00271 // empty 00272 } 00273 00274 00275 template <class T> 00276 inline T & 00277 TypedAttribute<T>::value () 00278 { 00279 return _value; 00280 } 00281 00282 00283 template <class T> 00284 inline const T & 00285 TypedAttribute<T>::value () const 00286 { 00287 return _value; 00288 } 00289 00290 00291 template <class T> 00292 const char * 00293 TypedAttribute<T>::typeName () const 00294 { 00295 return staticTypeName(); 00296 } 00297 00298 00299 template <class T> 00300 Attribute * 00301 TypedAttribute<T>::makeNewAttribute () 00302 { 00303 return new TypedAttribute<T>(); 00304 } 00305 00306 00307 template <class T> 00308 Attribute * 00309 TypedAttribute<T>::copy () const 00310 { 00311 Attribute * attribute = new TypedAttribute<T>(); 00312 attribute->copyValueFrom (*this); 00313 return attribute; 00314 } 00315 00316 00317 template <class T> 00318 void 00319 TypedAttribute<T>::writeValueTo (OStream &os, int version) const 00320 { 00321 Xdr::write <StreamIO> (os, _value); 00322 } 00323 00324 00325 template <class T> 00326 void 00327 TypedAttribute<T>::readValueFrom (IStream &is, int size, int version) 00328 { 00329 Xdr::read <StreamIO> (is, _value); 00330 } 00331 00332 00333 template <class T> 00334 void 00335 TypedAttribute<T>::copyValueFrom (const Attribute &other) 00336 { 00337 _value = cast(other)._value; 00338 } 00339 00340 00341 template <class T> 00342 TypedAttribute<T> * 00343 TypedAttribute<T>::cast (Attribute *attribute) 00344 { 00345 TypedAttribute<T> *t = 00346 dynamic_cast <TypedAttribute<T> *> (attribute); 00347 00348 if (t == 0) 00349 throw Iex::TypeExc ("Unexpected attribute type."); 00350 00351 return t; 00352 } 00353 00354 00355 template <class T> 00356 const TypedAttribute<T> * 00357 TypedAttribute<T>::cast (const Attribute *attribute) 00358 { 00359 const TypedAttribute<T> *t = 00360 dynamic_cast <const TypedAttribute<T> *> (attribute); 00361 00362 if (t == 0) 00363 throw Iex::TypeExc ("Unexpected attribute type."); 00364 00365 return t; 00366 } 00367 00368 00369 template <class T> 00370 inline TypedAttribute<T> & 00371 TypedAttribute<T>::cast (Attribute &attribute) 00372 { 00373 return *cast (&attribute); 00374 } 00375 00376 00377 template <class T> 00378 inline const TypedAttribute<T> & 00379 TypedAttribute<T>::cast (const Attribute &attribute) 00380 { 00381 return *cast (&attribute); 00382 } 00383 00384 00385 template <class T> 00386 inline void 00387 TypedAttribute<T>::registerAttributeType () 00388 { 00389 Attribute::registerAttributeType (staticTypeName(), makeNewAttribute); 00390 } 00391 00392 00393 template <class T> 00394 inline void 00395 TypedAttribute<T>::unRegisterAttributeType () 00396 { 00397 Attribute::unRegisterAttributeType (staticTypeName()); 00398 } 00399 00400 00401 } // namespace Imf 00402 00403 #if defined(OPENEXR_DLL) && defined(_MSC_VER) 00404 // Tell MS VC++ to disable "non dll-interface class used as base 00405 // for dll-interface class" and "no suitable definition provided 00406 // for explicit template" 00407 #pragma warning (disable : 4275 4661) 00408 00409 #if defined (ILMIMF_EXPORTS) 00410 #define IMF_EXPIMP_TEMPLATE 00411 #else 00412 #define IMF_EXPIMP_TEMPLATE extern 00413 #endif 00414 00415 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>; 00416 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>; 00417 00418 #pragma warning(default : 4251) 00419 #undef EXTERN_TEMPLATE 00420 #endif 00421 00422 // Metrowerks compiler wants the .cpp file inlined, too 00423 #ifdef __MWERKS__ 00424 #include <ImfAttribute.cpp> 00425 #endif 00426 00427 #endif