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: 2009-01-30 21:53:03 $
00007   Version:   $Revision: 1.24 $
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 __itkVisitorDispatcher_h
00018 #define __itkVisitorDispatcher_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 
00128 template< class TVisitedClass,
00129           class TVisitorBase,
00130           class TVisitFunctionPointerType= ITK_TYPENAME VisitorDispatcherTemplateHelper<TVisitedClass, TVisitorBase>::FunctionPointerType >
00131 class VisitorDispatcher
00132 {
00133 public:
00135 
00139   typedef TVisitedClass VisitedClass;
00140 
00145   typedef TVisitorBase VisitorBase;
00146 
00150   typedef typename VisitedClass::Pointer      VisitedClassPointer;
00151   typedef typename VisitedClass::ConstPointer VisitedClassConstPointer;
00152   typedef typename VisitorBase::Pointer       VisitorBasePointer;
00153 
00157   typedef TVisitFunctionPointerType VisitFunctionPointerType;
00158 
00162   typedef int ClassIDType;
00163 
00171   typedef std::map<ClassIDType, VisitFunctionPointerType> VisitorsArrayType;
00172   typedef typename VisitorsArrayType::value_type VisitorsArray_value_type;
00173 
00203   template<class TVisitorClass>
00204   inline static bool RegisterVisitor(TVisitorClass*, VisitFunctionPointerType visitor_function)
00205   {
00206     typedef TVisitorClass VisitorClass;
00207     bool status;
00208     Instance().m_MutexLock.Lock();
00209     status=Instance().visitors.insert(VisitorsArray_value_type(VisitorClass::CLID(),visitor_function)).second;
00210     Instance().m_MutexLock.Unlock();
00211     if ( status )
00212       {
00213       // Visitor class was successfully registered
00214       }
00215     else
00216       {
00217       // The visitor function was already registered.
00218       // FIXME: implement the proper error handler if required
00219       std::cout<<"Warning: Visitor "<<typeid(VisitorClass).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" was already registered! Ignoring the re-registration.\n";
00220       }
00221     return status;
00222   }
00224 
00238   static VisitFunctionPointerType Visit(VisitorBasePointer l);
00239 
00240 private:
00241 
00242   static VisitorDispatcher& Instance();
00243 
00244   static void CleanUP(void) { delete obj; }
00245 
00249   static VisitorDispatcher* obj;
00250 
00251   VisitorsArrayType visitors;
00252 
00257   mutable SimpleFastMutexLock m_MutexLock;
00258 
00259 };
00260 
00261 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00262 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>*
00263 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00264 ::obj = 0;
00265 
00266 extern "C"
00267 {
00268   typedef void(*c_void_cast)();
00269 }
00270 
00271 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00272 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>&
00273 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00274 ::Instance()
00275 {
00276   // Implementation of the singleton design pattern
00277   if (!obj) 
00278     { 
00279     // Create a new VisitorDispatcher object if we don't have it already.
00280     obj=new VisitorDispatcher;
00281 
00282     // Make sure that the object that we just created is also destroyed
00283     // when program finishes.
00284     atexit(reinterpret_cast<c_void_cast>(&CleanUP));
00285     }
00286   
00287   // Return the actual VisitorDispatcher object
00288   return *obj;
00289 }
00290 
00291 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00292 typename VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>::VisitFunctionPointerType
00293 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00294 ::Visit(VisitorBasePointer l)
00295 {
00296   typename VisitorsArrayType::const_iterator i = Instance().visitors.find(l->ClassID());
00297   if( i==Instance().visitors.end() )
00298   {
00299     // Visitor function not found... FIXME: write the proper error handler.
00300     std::cout<<"Error: Visitor "<<typeid(*l).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" not found!\n";
00301     throw FEMException(__FILE__, __LINE__, "FEM error");
00302   }
00303   return i->second;
00304 }
00305 
00306 }} // end namespace itk::fem
00307 
00308 #endif // __VisitorDispatcher_h
00309 

Generated at Sat Feb 28 13:50:12 2009 for ITK by doxygen 1.5.6 written by Dimitri van Heesch, © 1997-2000