Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
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 00031 // Needs to have iBase etc 00032 #include "csutil/scf_interface.h" 00033 00048 template<class Class> 00049 class scfImplementation : public virtual iBase 00050 { 00051 public: 00056 scfImplementation (Class *object, iBase *parent = 0) : 00057 scfObject (object), scfRefCount (1), scfParent (parent), 00058 scfWeakRefOwners (NULL) 00059 { 00060 if (scfParent) scfParent->IncRef (); 00061 } 00062 00063 // Cleanup 00064 virtual ~scfImplementation() 00065 { 00066 scfRemoveRefOwners (); 00067 } 00068 00072 void DecRef () 00073 { 00074 scfRefCount--; 00075 if (scfRefCount == 0) 00076 { 00077 scfRemoveRefOwners (); 00078 if (scfParent) scfParent->DecRef(); 00079 delete scfObject; 00080 } 00081 } 00082 00086 void IncRef () 00087 { 00088 scfRefCount++; 00089 } 00090 00094 int GetRefCount () 00095 { 00096 return scfRefCount; 00097 } 00098 00099 void AddRefOwner (iBase** ref_owner) 00100 { 00101 if (!this->scfWeakRefOwners) 00102 scfWeakRefOwners = new csArray<iBase**> (0, 4); 00103 scfWeakRefOwners->InsertSorted (ref_owner); 00104 } 00105 00106 void RemoveRefOwner (iBase** ref_owner) 00107 { 00108 if (!scfWeakRefOwners) 00109 return; 00110 00111 size_t index = scfWeakRefOwners->FindSortedKey ( 00112 csArrayCmp<iBase**, iBase**>(ref_owner)); 00113 00114 if (index != csArrayItemNotFound) 00115 scfWeakRefOwners->DeleteIndex (index); 00116 } 00117 00118 protected: 00119 Class *scfObject; 00120 00121 int scfRefCount; 00122 iBase *scfParent; 00123 csArray<iBase**>* scfWeakRefOwners; 00124 00125 void scfRemoveRefOwners () 00126 { 00127 if (!scfWeakRefOwners) 00128 return; 00129 00130 for (size_t i = 0; i < scfWeakRefOwners->Length (); i++) 00131 { 00132 iBase** p = (*scfWeakRefOwners)[i]; 00133 *p = NULL; 00134 } 00135 delete scfWeakRefOwners; 00136 scfWeakRefOwners = NULL; 00137 } 00138 00142 void *QueryInterface (scfInterfaceID iInterfaceID, 00143 scfInterfaceVersion iVersion) 00144 { 00145 // Default, just check iBase.. all objects have iBase 00146 if (iInterfaceID == scfInterfaceTraits<iBase>::GetID () && 00147 scfCompatibleVersion (iVersion, scfInterfaceTraits<iBase>::GetVersion ())) 00148 { 00149 scfObject->IncRef (); 00150 return CS_STATIC_CAST(iBase*,scfObject); 00151 } 00152 00153 // For embedded interfaces 00154 if (scfParent) 00155 return scfParent->QueryInterface (iInterfaceID, iVersion); 00156 00157 return NULL; 00158 } 00159 00164 template<class I> 00165 CS_FORCEINLINE void* GetInterface(scfInterfaceID iInterfaceID, 00166 scfInterfaceVersion iVersion) 00167 { 00168 if (iInterfaceID == scfInterfaceTraits<I>::GetID () && 00169 scfCompatibleVersion (iVersion, scfInterfaceTraits<I>::GetVersion ())) 00170 { 00171 scfObject->IncRef (); 00172 return CS_STATIC_CAST(I*, scfObject); 00173 } 00174 else 00175 { 00176 return NULL; 00177 } 00178 } 00179 }; 00180 00206 template<class If> 00207 class scfFakeInterface 00208 { 00209 public: 00210 struct InterfaceTraits 00211 { 00212 static CS_FORCEINLINE scfInterfaceVersion GetVersion() 00213 { 00214 return If::InterfaceTraits::GetVersion (); 00215 } 00216 static CS_FORCEINLINE char const * GetName() 00217 { 00218 return If::InterfaceTraits::GetName (); 00219 } 00220 }; 00221 }; 00222 00223 #define SCF_IN_IMPLEMENTATION_H 1 00224 // Instead of duplicating the code for every scfImplementationN and 00225 // scfImplementationExtN, the code is factored out into an include file 00226 // that we include multiple times. 00227 #define SCF_IMPL_N 1 00228 #include "scf_impl.h" 00229 #undef SCF_IMPL_N 00230 00231 #define SCF_IMPL_N 2 00232 #include "scf_impl.h" 00233 #undef SCF_IMPL_N 00234 00235 #define SCF_IMPL_N 3 00236 #include "scf_impl.h" 00237 #undef SCF_IMPL_N 00238 00239 #define SCF_IMPL_N 4 00240 #include "scf_impl.h" 00241 #undef SCF_IMPL_N 00242 00243 #define SCF_IMPL_N 5 00244 #include "scf_impl.h" 00245 #undef SCF_IMPL_N 00246 00247 #define SCF_IMPL_N 6 00248 #include "scf_impl.h" 00249 #undef SCF_IMPL_N 00250 /* 00251 #define SCF_IMPL_N 7 00252 #include "scf_impl.h" 00253 #undef SCF_IMPL_N 00254 00255 #define SCF_IMPL_N 8 00256 #include "scf_impl.h" 00257 #undef SCF_IMPL_N 00258 00259 #define SCF_IMPL_N 9 00260 #include "scf_impl.h" 00261 #undef SCF_IMPL_N 00262 00263 #define SCF_IMPL_N 10 00264 #include "scf_impl.h" 00265 #undef SCF_IMPL_N 00266 */ 00267 // Now all the scfImplementationExt are defined 00268 #define SCF_IMPL_EXT 00269 00270 #define SCF_IMPL_N 1 00271 #include "scf_impl.h" 00272 #undef SCF_IMPL_N 00273 00274 #define SCF_IMPL_N 2 00275 #include "scf_impl.h" 00276 #undef SCF_IMPL_N 00277 00278 #define SCF_IMPL_N 3 00279 #include "scf_impl.h" 00280 #undef SCF_IMPL_N 00281 00282 #define SCF_IMPL_N 4 00283 #include "scf_impl.h" 00284 #undef SCF_IMPL_N 00285 00286 #define SCF_IMPL_N 5 00287 #include "scf_impl.h" 00288 #undef SCF_IMPL_N 00289 /* 00290 #define SCF_IMPL_N 6 00291 #include "scf_impl.h" 00292 #undef SCF_IMPL_N 00293 00294 #define SCF_IMPL_N 7 00295 #include "scf_impl.h" 00296 #undef SCF_IMPL_N 00297 00298 #define SCF_IMPL_N 8 00299 #include "scf_impl.h" 00300 #undef SCF_IMPL_N 00301 00302 #define SCF_IMPL_N 9 00303 #include "scf_impl.h" 00304 #undef SCF_IMPL_N 00305 00306 #define SCF_IMPL_N 10 00307 #include "scf_impl.h" 00308 #undef SCF_IMPL_N 00309 */ 00310 #undef SCF_IMPL_EXT 00311 #undef SCF_IN_IMPLEMENTATION_H 00312 00317 /* Some examples: 00318 struct iFoo : virtual public iBase { 00319 SCF_INTERFACE(iFoo,0,0,1); 00320 }; 00321 00322 struct iBar : virtual public iBase { 00323 SCF_INTERFACE(iFoo,0,0,1); 00324 }; 00325 00326 class Foo : public scfImplementation1<Foo,iFoo> 00327 { 00328 public: 00329 Foo() : scfImplementationType(this) {} 00330 Foo(int, int) : scfImplementationType(0,0) {} 00331 }; 00332 00333 class Bar : public scfImplementationExt1<Bar,Foo,iBar> 00334 { 00335 public: 00336 Bar() : scfImplementationType(0) {} 00337 Bar(int x, int y) : scfImplementationType(0,x,y) {} 00338 }; 00339 */ 00340 00341 #endif 00342
Generated for Crystal Space by doxygen 1.4.4