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: 2003/09/10 14:29:44 $ 00007 Version: $Revision: 1.18 $ 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 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 Sat Mar 31 02:33:54 2007 for ITK by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2000