csutil/scf_implementation.h
Go to the documentation of this file.00001 /* 00002 Crystal Space Shared Class Facility (SCF) 00003 This header contains the parts of SCF that is needed when creating 00004 new classes which implements SCF interfaces. 00005 00006 Copyright (C) 2005 by Marten Svanfeldt 00007 (C) 2005 by Michael Adams 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License as published by the Free Software Foundation; either 00012 version 2 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Library General Public License for more details. 00018 00019 You should have received a copy of the GNU Library General Public 00020 License along with this library; if not, write to the Free 00021 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00022 */ 00023 00024 #ifndef __CSUTIL_SCF_IMPLEMENTATION_H__ 00025 #define __CSUTIL_SCF_IMPLEMENTATION_H__ 00026 00027 #include "csextern.h" 00028 00029 #include "csutil/array.h" 00030 #include "csutil/customallocated.h" 00031 #include "csutil/reftrackeraccess.h" 00032 00033 // Needs to have iBase etc 00034 #include "csutil/scf_interface.h" 00035 00036 // Control if we want to use preprocessed file or run generation each time 00037 #define SCF_IMPLGEN_PREPROCESSED 00038 00039 #ifndef CS_TYPENAME 00040 #ifdef CS_REF_TRACKER 00041 #include <typeinfo> 00042 #define CS_TYPENAME(x) typeid(x).name() 00043 #else 00044 #define CS_TYPENAME(x) 0 00045 #endif 00046 #endif 00047 00109 template<class If> 00110 class scfFakeInterface 00111 { 00112 public: 00113 struct InterfaceTraits 00114 { 00115 typedef If InterfaceType; 00116 CS_FORCEINLINE_TEMPLATEMETHOD 00117 static scfInterfaceVersion GetVersion() 00118 { return If::InterfaceTraits::GetVersion(); } 00119 CS_FORCEINLINE_TEMPLATEMETHOD static char const * GetName() 00120 { return If::InterfaceTraits::GetName(); } 00121 }; 00122 }; 00123 00129 template<class Class> 00130 class CS_CRYSTALSPACE_EXPORT scfImplementation : public virtual iBase, 00131 public CS::Memory::CustomAllocated 00132 { 00133 public: 00138 scfImplementation (Class *object, iBase *parent = 0) : 00139 scfObject (object), scfRefCount (1), scfParent (parent), 00140 scfWeakRefOwners (0) 00141 { 00142 csRefTrackerAccess::TrackConstruction (object); 00143 if (scfParent) scfParent->IncRef (); 00144 } 00145 00154 scfImplementation (const scfImplementation& /*other*/) : iBase() 00155 { 00156 CS_ASSERT_MSG ("To allow copying SCF classes, create a copy " 00157 "constructor in the derived class, and initialize scfImplementation " 00158 "like in the normal constructor, i.e. use " 00159 "\"scfImplementation (this)\".", false); 00160 } 00161 00162 // Cleanup 00163 virtual ~scfImplementation() 00164 { 00165 csRefTrackerAccess::TrackDestruction (scfObject, scfRefCount); 00166 scfRemoveRefOwners (); 00167 } 00168 00174 scfImplementation& operator= (const scfImplementation& /*other*/) 00175 { 00176 return *this; 00177 } 00178 00179 virtual void DecRef () 00180 { 00181 CS_ASSERT_MSG("Refcount decremented for destroyed object", 00182 scfRefCount != 0); 00183 csRefTrackerAccess::TrackDecRef (scfObject, scfRefCount); 00184 scfRefCount--; 00185 if (scfRefCount == 0) 00186 { 00187 scfRemoveRefOwners (); 00188 if (scfParent) scfParent->DecRef(); 00189 delete scfObject; 00190 } 00191 } 00192 00193 virtual void IncRef () 00194 { 00195 CS_ASSERT_MSG("Refcount incremented from inside dtor", 00196 scfRefCount != 0); 00197 csRefTrackerAccess::TrackIncRef (scfObject, scfRefCount); 00198 scfRefCount++; 00199 } 00200 00201 virtual int GetRefCount () 00202 { 00203 return scfRefCount; 00204 } 00205 00206 virtual void AddRefOwner (void** ref_owner) 00207 { 00208 if (!this->scfWeakRefOwners) 00209 scfWeakRefOwners = new WeakRefOwnerArray (0); 00210 scfWeakRefOwners->InsertSorted (ref_owner); 00211 } 00212 00213 virtual void RemoveRefOwner (void** ref_owner) 00214 { 00215 if (!scfWeakRefOwners) 00216 return; 00217 00218 size_t index = scfWeakRefOwners->FindSortedKey ( 00219 csArrayCmp<void**, void**>(ref_owner)); 00220 00221 if (index != csArrayItemNotFound) 00222 scfWeakRefOwners->DeleteIndex (index); 00223 } 00224 00225 protected: 00226 Class *scfObject; 00227 00228 int scfRefCount; 00229 iBase *scfParent; 00230 typedef csArray<void**, 00231 csArrayElementHandler<void**>, 00232 CS::Memory::AllocatorMalloc, 00233 csArrayCapacityLinear<csArrayThresholdFixed<4> > > WeakRefOwnerArray; 00234 WeakRefOwnerArray* scfWeakRefOwners; 00235 00236 void scfRemoveRefOwners () 00237 { 00238 if (!scfWeakRefOwners) 00239 return; 00240 00241 for (size_t i = 0; i < scfWeakRefOwners->GetSize (); i++) 00242 { 00243 void** p = (*scfWeakRefOwners)[i]; 00244 *p = 0; 00245 } 00246 delete scfWeakRefOwners; 00247 scfWeakRefOwners = 0; 00248 } 00249 00250 void *QueryInterface (scfInterfaceID iInterfaceID, 00251 scfInterfaceVersion iVersion) 00252 { 00253 // Default, just check iBase.. all objects have iBase 00254 if (iInterfaceID == scfInterfaceTraits<iBase>::GetID () && 00255 scfCompatibleVersion (iVersion, scfInterfaceTraits<iBase>::GetVersion ())) 00256 { 00257 scfObject->IncRef (); 00258 return static_cast<iBase*> (scfObject); 00259 } 00260 00261 // For embedded interfaces 00262 if (scfParent) 00263 return scfParent->QueryInterface (iInterfaceID, iVersion); 00264 00265 return 0; 00266 } 00267 }; 00268 00269 00270 /* Here the magic happens: generate scfImplementationN and 00271 * scfImplementationExtN classed */ 00272 #define SCF_IN_IMPLEMENTATION_H 1 00273 #if defined(DOXYGEN_RUN) || !defined(SCF_IMPLGEN_PREPROCESSED) 00274 // Generation is in separate file mostly for documentation generation purposes. 00275 #include "scf_implgen.h" 00276 #else 00277 #include "scf_implgen_p.h" 00278 #endif 00279 00280 #undef SCF_IN_IMPLEMENTATION_H 00281 #undef SCF_IMPLGEN_PREPROCESSED 00282 00285 #endif
Generated for Crystal Space 1.2 by doxygen 1.4.7