| 1 | #pragma once
 | 
|---|
| 2 | 
 | 
|---|
| 3 | 
 | 
|---|
| 4 | namespace Jenga{
 | 
|---|
| 5 | namespace Common{
 | 
|---|
| 6 | 
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #define MAX_HASHMAP 65535
 | 
|---|
| 9 | template<class T> class Hashmap
 | 
|---|
| 10 | {
 | 
|---|
| 11 |     T* hashArray[MAX_HASHMAP];
 | 
|---|
| 12 | 
 | 
|---|
| 13 | public:
 | 
|---|
| 14 |     virtual int GetHash( const char *keyName ) const
 | 
|---|
| 15 |     {
 | 
|---|
| 16 |         int key;
 | 
|---|
| 17 |         for(key=0;*keyName!='\0';keyName++){
 | 
|---|
| 18 |             key=((key<<8)+ *keyName )%MAX_HASHMAP;
 | 
|---|
| 19 |         }
 | 
|---|
| 20 |         return key;
 | 
|---|
| 21 |     }
 | 
|---|
| 22 | 
 | 
|---|
| 23 |     Hashmap()
 | 
|---|
| 24 |         : isIteratorReady( false )
 | 
|---|
| 25 |     {
 | 
|---|
| 26 |         memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
 | 
|---|
| 27 |     }
 | 
|---|
| 28 |     ~Hashmap()
 | 
|---|
| 29 |     {
 | 
|---|
| 30 |         Clear();
 | 
|---|
| 31 |     }
 | 
|---|
| 32 |     void Clear()
 | 
|---|
| 33 |     {
 | 
|---|
| 34 |         for( int i=0; i<MAX_HASHMAP; i++ )
 | 
|---|
| 35 |         {
 | 
|---|
| 36 |             T* temp = hashArray[i];
 | 
|---|
| 37 |             if( temp )
 | 
|---|
| 38 |             {
 | 
|---|
| 39 |                 delete temp;
 | 
|---|
| 40 |             }
 | 
|---|
| 41 |         }
 | 
|---|
| 42 |         memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
 | 
|---|
| 43 |     }
 | 
|---|
| 44 | 
 | 
|---|
| 45 |     // 内容を破棄せずにすべて抜き取る
 | 
|---|
| 46 |     void PullOutAll()
 | 
|---|
| 47 |     {
 | 
|---|
| 48 |         memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
 | 
|---|
| 49 |     }
 | 
|---|
| 50 | 
 | 
|---|
| 51 |     bool Put( T* value )
 | 
|---|
| 52 |     {
 | 
|---|
| 53 |         int key = GetHash( value->GetKeyName().c_str() );
 | 
|---|
| 54 | 
 | 
|---|
| 55 |         if(hashArray[key]){
 | 
|---|
| 56 |             T *temp = hashArray[key];
 | 
|---|
| 57 |             while( true ){
 | 
|---|
| 58 |                 if( temp->IsDuplication( value ) )
 | 
|---|
| 59 |                 {
 | 
|---|
| 60 |                     // 重複している
 | 
|---|
| 61 |                     return false;
 | 
|---|
| 62 |                 }
 | 
|---|
| 63 | 
 | 
|---|
| 64 |                 if( temp->GetChainNext() == NULL )
 | 
|---|
| 65 |                 {
 | 
|---|
| 66 |                     break;
 | 
|---|
| 67 |                 }
 | 
|---|
| 68 |                 temp = temp->GetChainNext();
 | 
|---|
| 69 |             }
 | 
|---|
| 70 |             temp->SetChainNext( value );
 | 
|---|
| 71 |         }
 | 
|---|
| 72 |         else{
 | 
|---|
| 73 |             hashArray[key] = value;
 | 
|---|
| 74 |         }
 | 
|---|
| 75 | 
 | 
|---|
| 76 |         return true;
 | 
|---|
| 77 |     }
 | 
|---|
| 78 | 
 | 
|---|
| 79 |     T* GetHashArrayElement( const char *keyName )
 | 
|---|
| 80 |     {
 | 
|---|
| 81 |         return hashArray[GetHash(keyName)];
 | 
|---|
| 82 |     }
 | 
|---|
| 83 |     const T* GetHashArrayElement( const char *keyName ) const
 | 
|---|
| 84 |     {
 | 
|---|
| 85 |         return hashArray[GetHash(keyName)];
 | 
|---|
| 86 |     }
 | 
|---|
| 87 | 
 | 
|---|
| 88 |     bool IsExistDuplicationKeyName( const std::string &keyName ) const
 | 
|---|
| 89 |     {
 | 
|---|
| 90 |         int key = GetHash( keyName.c_str() );
 | 
|---|
| 91 | 
 | 
|---|
| 92 |         if(hashArray[key]){
 | 
|---|
| 93 |             const T *temp = hashArray[key];
 | 
|---|
| 94 |             while( true ){
 | 
|---|
| 95 |                 if( temp->IsDuplication( keyName ) )
 | 
|---|
| 96 |                 {
 | 
|---|
| 97 |                     // 重複している
 | 
|---|
| 98 |                     return true;
 | 
|---|
| 99 |                 }
 | 
|---|
| 100 | 
 | 
|---|
| 101 |                 if( temp->GetChainNext() == NULL )
 | 
|---|
| 102 |                 {
 | 
|---|
| 103 |                     break;
 | 
|---|
| 104 |                 }
 | 
|---|
| 105 |                 temp = temp->GetChainNext();
 | 
|---|
| 106 |             }
 | 
|---|
| 107 |         }
 | 
|---|
| 108 | 
 | 
|---|
| 109 |         return false;
 | 
|---|
| 110 |     }
 | 
|---|
| 111 | 
 | 
|---|
| 112 |     bool IsExist( const T* value ) const
 | 
|---|
| 113 |     {
 | 
|---|
| 114 |         int key = GetHash( value->GetKeyName().c_str() );
 | 
|---|
| 115 | 
 | 
|---|
| 116 |         if(hashArray[key]){
 | 
|---|
| 117 |             const T *temp = hashArray[key];
 | 
|---|
| 118 |             while( true ){
 | 
|---|
| 119 |                 if( temp->IsDuplication( value ) )
 | 
|---|
| 120 |                 {
 | 
|---|
| 121 |                     // 重複している
 | 
|---|
| 122 |                     return true;
 | 
|---|
| 123 |                 }
 | 
|---|
| 124 | 
 | 
|---|
| 125 |                 if( temp->GetChainNext() == NULL )
 | 
|---|
| 126 |                 {
 | 
|---|
| 127 |                     break;
 | 
|---|
| 128 |                 }
 | 
|---|
| 129 |                 temp = temp->GetChainNext();
 | 
|---|
| 130 |             }
 | 
|---|
| 131 |         }
 | 
|---|
| 132 | 
 | 
|---|
| 133 |         return false;
 | 
|---|
| 134 |     }
 | 
|---|
| 135 | 
 | 
|---|
| 136 | 
 | 
|---|
| 137 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 138 |     // イテレータ
 | 
|---|
| 139 |     /////////////////////////////////////////////////////////////////
 | 
|---|
| 140 | private:
 | 
|---|
| 141 |     mutable std::vector<T*> iterator_Objects;
 | 
|---|
| 142 |     mutable int iterator_CurrentNext;
 | 
|---|
| 143 |     mutable bool isIteratorReady;
 | 
|---|
| 144 | public:
 | 
|---|
| 145 |     void Iterator_Init() const
 | 
|---|
| 146 |     {
 | 
|---|
| 147 |         iterator_Objects.clear();
 | 
|---|
| 148 |         iterator_CurrentNext = 0;
 | 
|---|
| 149 | 
 | 
|---|
| 150 |         for( int i=0; i<MAX_HASHMAP; i++ ){
 | 
|---|
| 151 |             if( hashArray[i] ){
 | 
|---|
| 152 |                 T* temp = hashArray[i];
 | 
|---|
| 153 |                 while( temp )
 | 
|---|
| 154 |                 {
 | 
|---|
| 155 |                     iterator_Objects.push_back( temp );
 | 
|---|
| 156 | 
 | 
|---|
| 157 |                     temp = (T*)temp->GetChainNext();
 | 
|---|
| 158 |                 }
 | 
|---|
| 159 |             }
 | 
|---|
| 160 |         }
 | 
|---|
| 161 | 
 | 
|---|
| 162 |         isIteratorReady = true;
 | 
|---|
| 163 |     }
 | 
|---|
| 164 |     void Iterator_Reset() const
 | 
|---|
| 165 |     {
 | 
|---|
| 166 |         if( !isIteratorReady )
 | 
|---|
| 167 |         {
 | 
|---|
| 168 |             Jenga::Throw( "イテレータの準備ができていない" );
 | 
|---|
| 169 |         }
 | 
|---|
| 170 |         iterator_CurrentNext = 0;
 | 
|---|
| 171 |     }
 | 
|---|
| 172 |     bool Iterator_HasNext() const
 | 
|---|
| 173 |     {
 | 
|---|
| 174 |         return ( iterator_CurrentNext < (int)iterator_Objects.size() );
 | 
|---|
| 175 |     }
 | 
|---|
| 176 |     T *Iterator_GetNext() const
 | 
|---|
| 177 |     {
 | 
|---|
| 178 |         return iterator_Objects[iterator_CurrentNext++];
 | 
|---|
| 179 |     }
 | 
|---|
| 180 |     int Iterator_GetMaxCount() const
 | 
|---|
| 181 |     {
 | 
|---|
| 182 |         return (int)iterator_Objects.size();
 | 
|---|
| 183 |     }
 | 
|---|
| 184 | 
 | 
|---|
| 185 | 
 | 
|---|
| 186 |     // XMLシリアライズ用
 | 
|---|
| 187 | private:
 | 
|---|
| 188 |     friend class boost::serialization::access;
 | 
|---|
| 189 |     BOOST_SERIALIZATION_SPLIT_MEMBER();
 | 
|---|
| 190 |     template<class Archive> void load(Archive& ar, const unsigned int version)
 | 
|---|
| 191 |     {
 | 
|---|
| 192 |         std::vector<T *> objects;
 | 
|---|
| 193 |         ar & BOOST_SERIALIZATION_NVP( objects );
 | 
|---|
| 194 | 
 | 
|---|
| 195 |         // 読み込み後の処理
 | 
|---|
| 196 |         Clear();
 | 
|---|
| 197 |         BOOST_FOREACH( T *object, objects )
 | 
|---|
| 198 |         {
 | 
|---|
| 199 |             Put( object );
 | 
|---|
| 200 |         }
 | 
|---|
| 201 |         Iterator_Init();
 | 
|---|
| 202 |     }
 | 
|---|
| 203 |     template<class Archive> void save(Archive& ar, const unsigned int version) const
 | 
|---|
| 204 |     {
 | 
|---|
| 205 |         // 保存準備
 | 
|---|
| 206 |         std::vector<T *> objects;
 | 
|---|
| 207 |         objects.clear();
 | 
|---|
| 208 |         Iterator_Reset();
 | 
|---|
| 209 |         while( Iterator_HasNext() )
 | 
|---|
| 210 |         {
 | 
|---|
| 211 |             objects.push_back( Iterator_GetNext() );
 | 
|---|
| 212 |         }
 | 
|---|
| 213 | 
 | 
|---|
| 214 |         ar & BOOST_SERIALIZATION_NVP( objects );
 | 
|---|
| 215 |     }
 | 
|---|
| 216 | };
 | 
|---|
| 217 | 
 | 
|---|
| 218 | template<class T> class ObjectInHashmap
 | 
|---|
| 219 | {
 | 
|---|
| 220 |     T *pNextObject;
 | 
|---|
| 221 | public:
 | 
|---|
| 222 | 
 | 
|---|
| 223 |     ObjectInHashmap()
 | 
|---|
| 224 |         : pNextObject( NULL )
 | 
|---|
| 225 |     {
 | 
|---|
| 226 |     }
 | 
|---|
| 227 |     ~ObjectInHashmap()
 | 
|---|
| 228 |     {
 | 
|---|
| 229 |         if( pNextObject )
 | 
|---|
| 230 |         {
 | 
|---|
| 231 |             delete pNextObject;
 | 
|---|
| 232 |         }
 | 
|---|
| 233 |     }
 | 
|---|
| 234 | 
 | 
|---|
| 235 |     virtual const std::string &GetKeyName() const = 0;
 | 
|---|
| 236 |     virtual bool IsDuplication( const T *value ) const
 | 
|---|
| 237 |     {
 | 
|---|
| 238 |         return ( GetKeyName() == value->GetName() );
 | 
|---|
| 239 |     }
 | 
|---|
| 240 |     virtual bool IsDuplication( const std::string &keyName ) const
 | 
|---|
| 241 |     {
 | 
|---|
| 242 |         return ( GetKeyName() == keyName );
 | 
|---|
| 243 |     }
 | 
|---|
| 244 | 
 | 
|---|
| 245 |     T *GetChainNext()
 | 
|---|
| 246 |     {
 | 
|---|
| 247 |         return pNextObject;
 | 
|---|
| 248 |     }
 | 
|---|
| 249 |     const T *GetChainNext() const
 | 
|---|
| 250 |     {
 | 
|---|
| 251 |         return pNextObject;
 | 
|---|
| 252 |     }
 | 
|---|
| 253 |     void SetChainNext( T *pNextObject )
 | 
|---|
| 254 |     {
 | 
|---|
| 255 |         this->pNextObject = pNextObject;
 | 
|---|
| 256 |     }
 | 
|---|
| 257 | };
 | 
|---|
| 258 | 
 | 
|---|
| 259 | 
 | 
|---|
| 260 | }}
 | 
|---|