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: 2002/10/01 21:49:54 $
00007   Version:   $Revision: 1.17 $
00008 
00009   Copyright (c) 2002 Insight 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 
00206   template<class TVisitorClass>
00207   inline static bool RegisterVisitor(TVisitorClass*, VisitFunctionPointerType visitor_function)
00208   {
00209     typedef TVisitorClass VisitorClass;
00210     bool status;
00211     Instance().m_MutexLock.Lock();
00212     status=Instance().visitors.insert(VisitorsArrayType::value_type(VisitorClass::CLID(),visitor_function)).second;
00213     Instance().m_MutexLock.Unlock();
00214     if ( status )
00215     {
00216       // Visitor class was successfully registered
00217 //      std::cout<<"Visitor "<<typeid(VisitorClass).name()<<" ("<<typeid(VisitedClass).name()<<") registered.\n";
00218 //      std::cout<<"Visitor registered:\n  Visitee:"<<typeid(TVisitedClass).name()<<"\n  Visitor:"<<typeid(TVisitorClass).name()<<"\n  Func   :"<<typeid(VisitFunctionPointerType).name()<<"\n\n";
00219     }
00220     else
00221     {
00222       // The visitor function was already registered.
00223       // FIXME: implement the proper error handler if required
00224       std::cout<<"Warning: Visitor "<<typeid(VisitorClass).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" was already registered! Ignoring the re-registration.\n";
00225     }
00226     return status;
00227   }
00228 
00242   static VisitFunctionPointerType Visit(VisitorBasePointer l);
00243 
00244 private:
00245 
00246   static VisitorDispatcher& Instance();
00247 
00248   static void CleanUP(void) { delete obj; }
00249 
00253   static VisitorDispatcher* obj;
00254 
00255   VisitorsArrayType visitors;
00256 
00261   mutable SimpleFastMutexLock m_MutexLock;
00262 
00263 };
00264 
00265 
00266 
00267 
00268 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00269 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>*
00270 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00271 ::obj = 0;
00272 
00273 
00274 
00275 
00276 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00277 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>&
00278 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00279 ::Instance()
00280 {
00281   // Implementation of the singleton design pattern
00282   if (!obj) 
00283   { 
00284     // Create a new VisitorDispatcher object if we don't have it already.
00285     obj=new VisitorDispatcher;
00286 
00287     // Make sure that the object that we just created is also destroyed
00288     // when program finishes.
00289     atexit(&CleanUP);
00290   }
00291 
00292   // Return the actual VisitorDispatcher object
00293   return *obj;
00294 }
00295 
00296 
00297 
00298 
00299 template<class TVisitedClass, class TVisitorBase, class TVisitFunctionPointerType>
00300 typename VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>::VisitFunctionPointerType
00301 VisitorDispatcher<TVisitedClass, TVisitorBase, TVisitFunctionPointerType>
00302 ::Visit(VisitorBasePointer l)
00303 {
00304   typename VisitorsArrayType::const_iterator i = Instance().visitors.find(l->ClassID());
00305   if( i==Instance().visitors.end() )
00306   {
00307     // Visitor function not found... FIXME: write the proper error handler.
00308     std::cout<<"Error: Visitor "<<typeid(*l).name()<<" that operates on objects of "<<typeid(VisitedClass).name()<<" not found!\n";
00309     throw FEMException(__FILE__, __LINE__, "FEM error");
00310   }
00311   return i->second;
00312 }
00313 
00314 
00315 
00316 
00317 }} // end namespace itk::fem
00318 
00319 #endif // __VisitorDispatcher_h

Generated at Fri May 21 01:15:33 2004 for ITK by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2000