00001 #ifndef IOKERNEL__METACLASS_VISITOR_H 00002 #define IOKERNEL__METACLASS_VISITOR_H 00003 00004 #include "meta_class.h" 00005 #include "common/suif_vector.h" 00006 00023 template<class VisitEntity> 00024 class MetaClassVisitor { 00025 public: 00026 MetaClassVisitor() : _entries( 0 ) { 00027 } 00028 00029 virtual ~MetaClassVisitor() {} 00030 00031 virtual void registerEntity( const MetaClass* meta_class, 00032 VisitEntity entity ) { 00033 clear_cache(); 00034 MetaClassId id = meta_class->get_meta_class_id(); 00035 for ( int i = _entries.size(); i<=id ; i++ ) { 00036 _entries.push_back( VectorEntry( 0 ) ); 00037 } 00038 _entries[ id ] = VectorEntry( entity ); 00039 } 00040 00041 virtual void registerDefaultEntity( VisitEntity entity ) { 00042 clear_cache(); 00043 if ( _entries.size() ) { 00044 _entries[0] = VectorEntry( entity ); 00045 } else { 00046 _entries.push_back( VectorEntry( entity ) ); 00047 } 00048 } 00049 00050 virtual VisitEntity retrieveEntity( const MetaClass* mc ) { 00051 MetaClassId id = mc->get_meta_class_id(); 00052 00053 VisitEntity entity; 00054 if ( (MetaClassId)_entries.size() <= id ) { 00055 // the look up goes beyond the vector size 00056 entity = 0; 00057 } else { 00058 VectorEntry entry = _entries[ id ]; 00059 if ( (!entry._entity) && (!entry._is_cached) ) { 00060 // the entry is not valid => look up inheritance link 00061 MetaClassId target; 00062 const MetaClass* parent = mc; 00063 do { 00064 parent = parent->get_link_meta_class(); 00065 00066 target = parent ? mc->get_meta_class_id() : 0; 00067 entry = _entries[ target ]; 00068 } while ( parent && !( entry._entity || entry._is_cached ) ); 00069 _entries[ id ]._entity = entry._entity; 00070 _entries[ id ]._is_cached = true; 00071 } 00072 entity = entry._entity; 00073 } 00074 return entity; 00075 } 00076 00077 virtual void clear_cache() { 00078 /* suif_vector<VectorEntry>*/ 00079 typename Vector::iterator current = _entries.begin(), 00080 end = _entries.end(); 00081 while ( current != end ) { 00082 if ( (*current)._is_cached ) { 00083 (*current)._entity = 0; 00084 (*current)._is_cached = false; 00085 } 00086 current++; 00087 } 00088 } 00089 private: 00090 struct VectorEntry { 00091 VectorEntry( VisitEntity e = 0 ) : _entity( e ), _is_cached( false ) {} 00092 VisitEntity _entity; 00093 bool _is_cached; 00094 }; 00095 typedef suif_vector<VectorEntry> Vector; 00096 suif_vector<VectorEntry> _entries; 00097 }; 00098 00099 00100 #endif