Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 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 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00042 //----------------------------------------------------------------------------// 00043 00044 #ifndef _INCLUDED_Field3D_REF_COUNT_H_ 00045 #define _INCLUDED_Field3D_REF_COUNT_H_ 00046 00047 #define FIELD3D_USE_ATOMIC_COUNT 00048 00049 //----------------------------------------------------------------------------// 00050 #include <boost/intrusive_ptr.hpp> 00051 00052 #ifdef FIELD3D_USE_ATOMIC_COUNT 00053 #include <boost/detail/atomic_count.hpp> 00054 #else 00055 #include <boost/thread/mutex.hpp> 00056 #endif 00057 00058 #include <string.h> 00059 #include "Traits.h" 00060 #include "ns.h" 00061 00062 FIELD3D_NAMESPACE_OPEN 00063 00064 //----------------------------------------------------------------------------// 00065 // Field RTTI Replacement 00066 //----------------------------------------------------------------------------// 00067 00068 #define DEFINE_CHECK_RTTI_CALL \ 00069 virtual bool checkRTTI(const char *typenameStr) \ 00070 { return matchRTTI(typenameStr); } \ 00071 00072 #define DEFINE_MATCH_RTTI_CALL \ 00073 bool matchRTTI(const char *typenameStr) \ 00074 { \ 00075 if (strcmp(typenameStr,classType()) == 0) { \ 00076 return true; \ 00077 } \ 00078 return base::matchRTTI(typenameStr); \ 00079 } \ 00080 00081 #define DEFINE_FIELD_RTTI_CONCRETE_CLASS \ 00082 DEFINE_CHECK_RTTI_CALL \ 00083 DEFINE_MATCH_RTTI_CALL \ 00084 00085 #define DEFINE_FIELD_RTTI_ABSTRACT_CLASS \ 00086 DEFINE_MATCH_RTTI_CALL \ 00087 00088 //----------------------------------------------------------------------------// 00089 00090 class RefBase 00091 { 00092 public: 00093 00094 // Typedefs ------------------------------------------------------------------ 00095 00096 typedef boost::intrusive_ptr<RefBase> Ptr; 00097 00098 // Constructors -------------------------------------------------------------- 00099 00102 00103 RefBase() 00104 : m_counter(0) 00105 {} 00106 00108 RefBase(const RefBase&) 00109 : m_counter(0) 00110 {} 00111 00113 RefBase& operator= (const RefBase&) 00114 { return *this; } 00115 00117 virtual ~RefBase() 00118 {} 00119 00121 00122 // Reference counting -------------------------------------------------------- 00123 00125 size_t refcnt() 00126 { return m_counter; } 00127 00129 void ref() const 00130 { 00131 #ifndef FIELD3D_USE_ATOMIC_COUNT 00132 boost::mutex::scoped_lock lock(m_refMutex); 00133 #endif 00134 ++m_counter; 00135 } 00136 00138 void unref() const 00139 { 00140 #ifndef FIELD3D_USE_ATOMIC_COUNT 00141 boost::mutex::scoped_lock lock(m_refMutex); 00142 #endif 00143 --m_counter; 00144 // since we use intrusive_pointer no need 00145 // to delete the object ourselves. 00146 } 00147 00148 // RTTI replacement ---------------------------------------------------------- 00149 00158 00159 00160 00163 virtual bool checkRTTI(const char *typenameStr) = 0; 00164 00167 bool matchRTTI(const char *typenameStr) 00168 { 00169 if (strcmp(classType(), typenameStr) == 0) 00170 return true; 00171 return false; 00172 } 00173 00174 static const char *classType() 00175 { 00176 return "RefBase"; 00177 } 00178 00180 00181 private: 00182 00184 #ifdef FIELD3D_USE_ATOMIC_COUNT 00185 mutable boost::detail::atomic_count m_counter; 00186 #else 00187 mutable long m_counter; 00189 mutable boost::mutex m_refMutex; 00190 #endif 00191 00192 }; 00193 00194 //----------------------------------------------------------------------------// 00195 // Intrusive Pointer reference counting 00196 //----------------------------------------------------------------------------// 00197 00198 inline void 00199 intrusive_ptr_add_ref(RefBase* r) 00200 { 00201 r->ref(); 00202 } 00203 00204 //----------------------------------------------------------------------------// 00205 00206 inline void 00207 intrusive_ptr_release(RefBase* r) 00208 { 00209 r->unref(); 00210 00211 if (r->refcnt() == 0) 00212 delete r; 00213 } 00214 00215 //----------------------------------------------------------------------------// 00216 // field_dynamic_cast 00217 //----------------------------------------------------------------------------// 00218 00222 template <class Field_T> 00223 typename Field_T::Ptr 00224 field_dynamic_cast(RefBase::Ptr field) 00225 { 00226 if (!field) 00227 return NULL; 00228 00229 const char *tgtTypeString = Field_T::classType(); 00230 00231 if (field->checkRTTI(tgtTypeString)) { 00232 return static_cast<Field_T*>(field.get()); 00233 } else { 00234 return NULL; 00235 } 00236 } 00237 00238 //#define FIELD_DYNAMIC_CAST boost::dynamic_pointer_cast 00239 #define FIELD_DYNAMIC_CAST field_dynamic_cast 00240 00241 //----------------------------------------------------------------------------// 00242 00243 FIELD3D_NAMESPACE_HEADER_CLOSE 00244 00245 //----------------------------------------------------------------------------// 00246 00247 #endif // Include guard 00248