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:
00137 
00141   typedef TVisitedClass VisitedClass;
00142 
00147   typedef TVisitorBase VisitorBase;
00148 
00152   typedef typename VisitedClass::Pointer VisitedClassPointer;
00153   typedef typename VisitedClass::ConstPointer VisitedClassConstPointer;
00154   typedef typename VisitorBase::Pointer VisitorBasePointer;
00155 
00156 
00157 
00161   typedef TVisitFunctionPointerType VisitFunctionPointerType;
00162 
00166   typedef int ClassIDType;
00167 
00175   typedef std::map<ClassIDType, VisitFunctionPointerType> VisitorsArrayType;
00176   typedef typename VisitorsArrayType::value_type VisitorsArray_value_type;
00177 
00207   template<class TVisitorClass>
00208   inline static bool RegisterVisitor(TVisitorClass*, VisitFunctionPointerType visitor_function)
00209   {
00210     typedef TVisitorClass VisitorClass;
00211     bool status;
00212     Instance().m_MutexLock.Lock();
00213     status=Instance().visitors.insert(VisitorsArray_value_type(VisitorClass::CLID(),visitor_function)).second;
00214     Instance().m_MutexLock.Unlock();
00215     if ( status )
00216     {
00217       // Visitor class was successfully registered
00218 //      std::cout<<"Visitor "<<typeid(VisitorClass).name()<<" ("<<typeid(VisitedClass).name()<<") registered.\n";
00219 //      std::cout<<"Visitor registered:\n  Visitee:"<<typeid(TVisitedClass).name()<<"\n  Visitor:"<<typeid(TVisitorClass).name()<<"\n  Func   :"<<typeid(VisitFunctionPointerType).name()<<"\n\n";
00220     }
00221     else
00222     {
00223       // The visitor function was already registered.
00224       // FIXME: implement the proper error handler if required
00225       std::cout<<"Warning: Visitor "<<typeid(VisitorClass).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" was already registered! Ignoring the re-registration.\n";
00226     }
00227     return status;
00228   }
00229 
00243   static VisitFunctionPointerType Visit(VisitorBasePointer l);
00244 
00245 private:
00246 
00247   static VisitorDispatcher& Instance();
00248 
00249   static void CleanUP(void) { delete obj; }
00250 
00254   static VisitorDispatcher* obj;
00255 
00256   VisitorsArrayType visitors;
00257 
00262   mutable SimpleFastMutexLock m_MutexLock;
00263 
00264 };
00265 
00266 
00267 
00268 
00269 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00270 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>*
00271 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00272 ::obj = 0;
00273 
00274 
00275 
00276 extern "C"
00277 {
00278   typedef void(*c_void_cast)();
00279 }
00280 
00281 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00282 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>&
00283 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00284 ::Instance()
00285 {
00286   // Implementation of the singleton design pattern
00287   if (!obj) 
00288   { 
00289     // Create a new VisitorDispatcher object if we don't have it already.
00290     obj=new VisitorDispatcher;
00291 
00292     // Make sure that the object that we just created is also destroyed
00293     // when program finishes.
00294     atexit(reinterpret_cast<c_void_cast>(&CleanUP));
00295   }
00296 
00297   // Return the actual VisitorDispatcher object
00298   return *obj;
00299 }
00300 
00301 
00302 
00303 
00304 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00305 typename VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>::VisitFunctionPointerType
00306 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00307 ::Visit(VisitorBasePointer l)
00308 {
00309   typename VisitorsArrayType::const_iterator i = Instance().visitors.find(l->ClassID());
00310   if( i==Instance().visitors.end() )
00311   {
00312     // Visitor function not found... FIXME: write the proper error handler.
00313     std::cout<<"Error: Visitor "<<typeid(*l).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" not found!\n";
00314     throw FEMException(__FILE__, __LINE__, "FEM error");
00315   }
00316   return i->second;
00317 }
00318 
00319 
00320 
00321 
00322 }} // end namespace itk::fem
00323 
00324 #endif // __VisitorDispatcher_h

Generated at Thu May 25 00:15:30 2006 for ITK by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2000