| [215] | 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 | 
 | 
|---|
| [270] | 45 |     // 内容を破棄せずにすべて抜き取る
 | 
|---|
 | 46 |     void PullOutAll()
 | 
|---|
 | 47 |     {
 | 
|---|
 | 48 |         memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) );
 | 
|---|
 | 49 |     }
 | 
|---|
 | 50 | 
 | 
|---|
| [215] | 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 |     }
 | 
|---|
| [270] | 83 |     const T* GetHashArrayElement( const char *keyName ) const
 | 
|---|
 | 84 |     {
 | 
|---|
 | 85 |         return hashArray[GetHash(keyName)];
 | 
|---|
 | 86 |     }
 | 
|---|
| [215] | 87 | 
 | 
|---|
| [564] | 88 |     bool IsExistDuplicationKeyName( const std::string &keyName ) const
 | 
|---|
| [215] | 89 |     {
 | 
|---|
 | 90 |         int key = GetHash( keyName.c_str() );
 | 
|---|
 | 91 | 
 | 
|---|
 | 92 |         if(hashArray[key]){
 | 
|---|
| [564] | 93 |             const T *temp = hashArray[key];
 | 
|---|
| [215] | 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 | 
 | 
|---|
| [564] | 112 |     bool IsExist( const T* value ) const
 | 
|---|
 | 113 |     {
 | 
|---|
 | 114 |         int key = GetHash( value->GetKeyName().c_str() );
 | 
|---|
| [215] | 115 | 
 | 
|---|
| [564] | 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 | 
 | 
|---|
| [215] | 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 |     }
 | 
|---|
| [270] | 249 |     const T *GetChainNext() const
 | 
|---|
 | 250 |     {
 | 
|---|
 | 251 |         return pNextObject;
 | 
|---|
 | 252 |     }
 | 
|---|
| [215] | 253 |     void SetChainNext( T *pNextObject )
 | 
|---|
 | 254 |     {
 | 
|---|
 | 255 |         this->pNextObject = pNextObject;
 | 
|---|
 | 256 |     }
 | 
|---|
 | 257 | };
 | 
|---|
 | 258 | 
 | 
|---|
 | 259 | 
 | 
|---|
 | 260 | }}
 | 
|---|