Field3D
RefCount.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
42 //----------------------------------------------------------------------------//
43 
44 #ifndef _INCLUDED_Field3D_REF_COUNT_H_
45 #define _INCLUDED_Field3D_REF_COUNT_H_
46 
47 #define FIELD3D_USE_ATOMIC_COUNT
48 
49 //----------------------------------------------------------------------------//
50 #include <boost/intrusive_ptr.hpp>
51 
52 #ifdef FIELD3D_USE_ATOMIC_COUNT
53 #include <boost/detail/atomic_count.hpp>
54 #else
55 #include <boost/thread/mutex.hpp>
56 #endif
57 
58 #include <string.h>
59 #include "Traits.h"
60 #include "ns.h"
61 
63 
64 //----------------------------------------------------------------------------//
65 // Field RTTI Replacement
66 //----------------------------------------------------------------------------//
67 
68 #define DEFINE_CHECK_RTTI_CALL \
69  virtual bool checkRTTI(const char *typenameStr) \
70  { return matchRTTI(typenameStr); } \
71 
72 #define DEFINE_MATCH_RTTI_CALL \
73  bool matchRTTI(const char *typenameStr) \
74  { \
75  if (strcmp(typenameStr,classType()) == 0) { \
76  return true; \
77  } \
78  return base::matchRTTI(typenameStr); \
79  } \
80 
81 #define DEFINE_FIELD_RTTI_CONCRETE_CLASS \
82  DEFINE_CHECK_RTTI_CALL \
83  DEFINE_MATCH_RTTI_CALL \
84 
85 #define DEFINE_FIELD_RTTI_ABSTRACT_CLASS \
86  DEFINE_MATCH_RTTI_CALL \
87 
88 //----------------------------------------------------------------------------//
89 
90 class RefBase
91 {
92 public:
93 
94  // Typedefs ------------------------------------------------------------------
95 
96  typedef boost::intrusive_ptr<RefBase> Ptr;
97 
98  // Constructors --------------------------------------------------------------
99 
102 
104  : m_counter(0)
105  {}
106 
108  RefBase(const RefBase&)
109  : m_counter(0)
110  {}
111 
114  { return *this; }
115 
117  virtual ~RefBase()
118  {}
119 
121 
122  // Reference counting --------------------------------------------------------
123 
125  size_t refcnt()
126  { return m_counter; }
127 
129  void ref() const
130  {
131 #ifndef FIELD3D_USE_ATOMIC_COUNT
132  boost::mutex::scoped_lock lock(m_refMutex);
133 #endif
134  ++m_counter;
135  }
136 
138  void unref() const
139  {
140 #ifndef FIELD3D_USE_ATOMIC_COUNT
141  boost::mutex::scoped_lock lock(m_refMutex);
142 #endif
143  --m_counter;
144  // since we use intrusive_pointer no need
145  // to delete the object ourselves.
146  }
147 
148  // RTTI replacement ----------------------------------------------------------
149 
158 
163  virtual bool checkRTTI(const char *typenameStr) = 0;
164 
167  bool matchRTTI(const char *typenameStr)
168  {
169  if (strcmp(classType(), typenameStr) == 0)
170  return true;
171  return false;
172  }
173 
174  static const char *classType()
175  {
176  return "RefBase";
177  }
178 
180 
181 private:
182 
184 #ifdef FIELD3D_USE_ATOMIC_COUNT
185  mutable boost::detail::atomic_count m_counter;
186 #else
187  mutable long m_counter;
189  mutable boost::mutex m_refMutex;
190 #endif
191 
192 };
193 
194 //----------------------------------------------------------------------------//
195 // Intrusive Pointer reference counting
196 //----------------------------------------------------------------------------//
197 
198 inline void
200 {
201  r->ref();
202 }
203 
204 //----------------------------------------------------------------------------//
205 
206 inline void
208 {
209  r->unref();
210 
211  if (r->refcnt() == 0)
212  delete r;
213 }
214 
215 //----------------------------------------------------------------------------//
216 // field_dynamic_cast
217 //----------------------------------------------------------------------------//
218 
222 template <class Field_T>
223 typename Field_T::Ptr
225 {
226  if (!field)
227  return NULL;
228 
229  const char *tgtTypeString = Field_T::classType();
230 
231  if (field->checkRTTI(tgtTypeString)) {
232  return static_cast<Field_T*>(field.get());
233  } else {
234  return NULL;
235  }
236 }
237 
238 //#define FIELD_DYNAMIC_CAST boost::dynamic_pointer_cast
239 #define FIELD_DYNAMIC_CAST field_dynamic_cast
240 
241 //----------------------------------------------------------------------------//
242 
244 
245 //----------------------------------------------------------------------------//
246 
247 #endif // Include guard
248 
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition: RefCount.h:224
boost::detail::atomic_count m_counter
For boost intrusive pointer.
Definition: RefCount.h:185
void intrusive_ptr_release(RefBase *r)
Definition: RefCount.h:207
static const char * classType()
Definition: RefCount.h:174
RefBase & operator=(const RefBase &)
Assignment operator.
Definition: RefCount.h:113
bool matchRTTI(const char *typenameStr)
Performs a check to see if the given typename string matches this class&#39; This needs to be implemented...
Definition: RefCount.h:167
RefBase(const RefBase &)
Copy constructor.
Definition: RefCount.h:108
boost::intrusive_ptr< RefBase > Ptr
Definition: RefCount.h:96
void intrusive_ptr_add_ref(RefBase *r)
Definition: RefCount.h:199
RefBase()
Definition: RefCount.h:103
void unref() const
Used by boost::intrusive_pointer.
Definition: RefCount.h:138
virtual ~RefBase()
Destructor.
Definition: RefCount.h:117
size_t refcnt()
Used by boost::intrusive_pointer.
Definition: RefCount.h:125
virtual bool checkRTTI(const char *typenameStr)=0
This function is only implemented by concrete classes and triggers the actual RTTI check through matc...
void ref() const
Used by boost::intrusive_pointer.
Definition: RefCount.h:129
#define FIELD3D_NAMESPACE_OPEN
Definition: ns.h:56