Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkVisitorDispatcher.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkVisitorDispatcher.h,v $
00005   Language:  C++
00006   Date:      $Date: 2005/11/17 19:27:40 $
00007   Version:   $Revision: 1.23 $
00008 
00009   Copyright (c) Insight Software Consortium. All rights reserved.
00010   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012      This software is distributed WITHOUT ANY WARRANTY; without even 
00013      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014      PURPOSE.  See the above copyright notices for more information.
00015 
00016 =========================================================================*/
00017 #ifndef __VisitorDispatcher_h
00018 #define __VisitorDispatcher_h
00019 
00020 #include "itkFEMMacro.h"
00021 #include "itkFEMException.h"
00022 #include "itkFastMutexLock.h"
00023 #include <typeinfo>
00024 #include <map>
00025 
00026 namespace itk {
00027 namespace fem {
00028 
00029 template< class TVisitedClass,
00030           class TVisitorBase>
00031 class VisitorDispatcherTemplateHelper
00032 {
00033 public:
00034   typedef void (*FunctionPointerType )(typename TVisitedClass::ConstPointer, typename TVisitorBase::Pointer);
00035 };
00036   
00037 
00038 
00039 
00131 template< class TVisitedClass,
00132           class TVisitorBase,
00133           class TVisitFunctionPointerType= ITK_TYPENAME VisitorDispatcherTemplateHelper<TVisitedClass, TVisitorBase>::FunctionPointerType >
00134 class VisitorDispatcher
00135 {
00136 public:
00138 
00142   typedef TVisitedClass VisitedClass;
00143 
00148   typedef TVisitorBase VisitorBase;
00149 
00153   typedef typename VisitedClass::Pointer VisitedClassPointer;
00154   typedef typename VisitedClass::ConstPointer VisitedClassConstPointer;
00155   typedef typename VisitorBase::Pointer VisitorBasePointer;
00156 
00157 
00158 
00162   typedef TVisitFunctionPointerType VisitFunctionPointerType;
00163 
00167   typedef int ClassIDType;
00168 
00176   typedef std::map<ClassIDType, VisitFunctionPointerType> VisitorsArrayType;
00177   typedef typename VisitorsArrayType::value_type VisitorsArray_value_type;
00178 
00208   template<class TVisitorClass>
00209   inline static bool RegisterVisitor(TVisitorClass*, VisitFunctionPointerType visitor_function)
00210   {
00211     typedef TVisitorClass VisitorClass;
00212     bool status;
00213     Instance().m_MutexLock.Lock();
00214     status=Instance().visitors.insert(VisitorsArray_value_type(VisitorClass::CLID(),visitor_function)).second;
00215     Instance().m_MutexLock.Unlock();
00216     if ( status )
00217     {
00218       // Visitor class was successfully registered
00219 //      std::cout<<"Visitor "<<typeid(VisitorClass).name()<<" ("<<typeid(VisitedClass).name()<<") registered.\n";
00220 //      std::cout<<"Visitor registered:\n  Visitee:"<<typeid(TVisitedClass).name()<<"\n  Visitor:"<<typeid(TVisitorClass).name()<<"\n  Func   :"<<typeid(VisitFunctionPointerType).name()<<"\n\n";
00221     }
00222     else
00223     {
00224       // The visitor function was already registered.
00225       // FIXME: implement the proper error handler if required
00226       std::cout<<"Warning: Visitor "<<typeid(VisitorClass).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" was already registered! Ignoring the re-registration.\n";
00227     }
00228     return status;
00229   }
00231 
00245   static VisitFunctionPointerType Visit(VisitorBasePointer l);
00246 
00247 private:
00248 
00249   static VisitorDispatcher& Instance();
00250 
00251   static void CleanUP(void) { delete obj; }
00252 
00256   static VisitorDispatcher* obj;
00257 
00258   VisitorsArrayType visitors;
00259 
00264   mutable SimpleFastMutexLock m_MutexLock;
00265 
00266 };
00267 
00268 
00269 
00270 
00271 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00272 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>*
00273 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00274 ::obj = 0;
00275 
00276 
00277 
00278 extern "C"
00279 {
00280   typedef void(*c_void_cast)();
00281 }
00282 
00283 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00284 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>&
00285 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00286 ::Instance()
00287 {
00288   // Implementation of the singleton design pattern
00289   if (!obj) 
00290   { 
00291     // Create a new VisitorDispatcher object if we don't have it already.
00292     obj=new VisitorDispatcher;
00293 
00294     // Make sure that the object that we just created is also destroyed
00295     // when program finishes.
00296     atexit(reinterpret_cast<c_void_cast>(&CleanUP));
00297   }
00298 
00299   // Return the actual VisitorDispatcher object
00300   return *obj;
00301 }
00302 
00303 
00304 
00305 
00306 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00307 typename VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>::VisitFunctionPointerType
00308 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00309 ::Visit(VisitorBasePointer l)
00310 {
00311   typename VisitorsArrayType::const_iterator i = Instance().visitors.find(l->ClassID());
00312   if( i==Instance().visitors.end() )
00313   {
00314     // Visitor function not found... FIXME: write the proper error handler.
00315     std::cout<<"Error: Visitor "<<typeid(*l).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" not found!\n";
00316     throw FEMException(__FILE__, __LINE__, "FEM error");
00317   }
00318   return i->second;
00319 }
00320 
00321 
00322 
00323 
00324 }} // end namespace itk::fem
00325 
00326 #endif // __VisitorDispatcher_h
00327 

Generated at Mon Mar 12 03:25:18 2007 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000