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/reftrackeraccess.h" 00031 00032 // Needs to have iBase etc 00033 #include "csutil/scf_interface.h" 00034 00035 #ifndef CS_TYPENAME 00036 #ifdef CS_REF_TRACKER 00037 #include <typeinfo> 00038 #define CS_TYPENAME(x) typeid(x).name() 00039 #else 00040 #define CS_TYPENAME(x) 0 00041 #endif 00042 #endif 00043 00105 template<class If> 00106 class scfFakeInterface 00107 { 00108 public: 00109 struct InterfaceTraits 00110 { 00111 typedef If InterfaceType; 00112 CS_FORCEINLINE static scfInterfaceVersion GetVersion() 00113 { return If::InterfaceTraits::GetVersion(); } 00114 CS_FORCEINLINE static char const * GetName() 00115 { return If::InterfaceTraits::GetName(); } 00116 }; 00117 }; 00118 00124 template<class Class> 00125 class CS_CRYSTALSPACE_EXPORT scfImplementation : public virtual iBase 00126 { 00127 public: 00132 scfImplementation (Class *object, iBase *parent = 0) : 00133 scfObject (object), scfRefCount (1), scfParent (parent), 00134 scfWeakRefOwners (0) 00135 { 00136 csRefTrackerAccess::TrackConstruction (object); 00137 if (scfParent) scfParent->IncRef (); 00138 } 00139 00148 scfImplementation (const scfImplementation& /*other*/) : iBase() 00149 { 00150 CS_ASSERT_MSG ("To allow copying SCF classes, create a copy " 00151 "constructor in the derived class, and initialize scfImplementation " 00152 "like in the normal constructor, i.e. use " 00153 "\"scfImplementation (this)\".", false); 00154 } 00155 00156 // Cleanup 00157 virtual ~scfImplementation() 00158 { 00159 csRefTrackerAccess::TrackDestruction (scfObject, scfRefCount); 00160 scfRemoveRefOwners (); 00161 } 00162 00168 scfImplementation& operator= (const scfImplementation& /*other*/) 00169 { 00170 return *this; 00171 } 00172 00173 virtual void DecRef () 00174 { 00175 CS_ASSERT_MSG("Refcount decremented for destroyed object", 00176 scfRefCount != 0); 00177 csRefTrackerAccess::TrackDecRef (scfObject, scfRefCount); 00178 scfRefCount--; 00179 if (scfRefCount == 0) 00180 { 00181 scfRemoveRefOwners (); 00182 if (scfParent) scfParent->DecRef(); 00183 delete scfObject; 00184 } 00185 } 00186 00187 virtual void IncRef () 00188 { 00189 CS_ASSERT_MSG("Refcount incremented from inside dtor", 00190 scfRefCount != 0); 00191 csRefTrackerAccess::TrackIncRef (scfObject, scfRefCount); 00192 scfRefCount++; 00193 } 00194 00195 virtual int GetRefCount () 00196 { 00197 return scfRefCount; 00198 } 00199 00200 virtual void AddRefOwner (iBase** ref_owner) 00201 { 00202 if (!this->scfWeakRefOwners) 00203 scfWeakRefOwners = new csArray<iBase**> (0, 4); 00204 scfWeakRefOwners->InsertSorted (ref_owner); 00205 } 00206 00207 virtual void RemoveRefOwner (iBase** ref_owner) 00208 { 00209 if (!scfWeakRefOwners) 00210 return; 00211 00212 size_t index = scfWeakRefOwners->FindSortedKey ( 00213 csArrayCmp<iBase**, iBase**>(ref_owner)); 00214 00215 if (index != csArrayItemNotFound) 00216 scfWeakRefOwners->DeleteIndex (index); 00217 } 00218 00219 protected: 00220 Class *scfObject; 00221 00222 int scfRefCount; 00223 iBase *scfParent; 00224 csArray<iBase**>* scfWeakRefOwners; 00225 00226 void scfRemoveRefOwners () 00227 { 00228 if (!scfWeakRefOwners) 00229 return; 00230 00231 for (size_t i = 0; i < scfWeakRefOwners->Length (); i++) 00232 { 00233 iBase** p = (*scfWeakRefOwners)[i]; 00234 *p = 0; 00235 } 00236 delete scfWeakRefOwners; 00237 scfWeakRefOwners = 0; 00238 } 00239 00240 void *QueryInterface (scfInterfaceID iInterfaceID, 00241 scfInterfaceVersion iVersion) 00242 { 00243 // Default, just check iBase.. all objects have iBase 00244 if (iInterfaceID == scfInterfaceTraits<iBase>::GetID () && 00245 scfCompatibleVersion (iVersion, scfInterfaceTraits<iBase>::GetVersion ())) 00246 { 00247 scfObject->IncRef (); 00248 return CS_STATIC_CAST(iBase*,scfObject); 00249 } 00250 00251 // For embedded interfaces 00252 if (scfParent) 00253 return scfParent->QueryInterface (iInterfaceID, iVersion); 00254 00255 return 0; 00256 } 00257 }; 00258 00259 00260 /* Here the magic happens: generate scfImplementationN and 00261 * scfImplementationExtN classed */ 00262 #define SCF_IN_IMPLEMENTATION_H 1 00263 // Generation is in separate file mostly for documentation generation purposes. 00264 #include "scf_implgen.h" 00265 #undef SCF_IN_IMPLEMENTATION_H 00266 00269 #endif
Generated for Crystal Space by doxygen 1.4.6