CrystalSpace

Public API Reference

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