| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 | //-----------------------------------------------------------------------------// Copyright (c) 2012 GarageGames, LLC//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS// IN THE SOFTWARE.//-----------------------------------------------------------------------------#include "console/simDictionary.h"#include "console/simBase.h"//----------------------------------------------------------------------------//----------------------------------------------------------------------------extern U32 HashPointer(StringTableEntry e);SimNameDictionary::SimNameDictionary(){#ifndef USE_NEW_SIMDICTIONARY   hashTable = NULL;   hashTableSize = DefaultTableSize;   hashEntryCount = 0;#endif   mutex = Mutex::createMutex();}SimNameDictionary::~SimNameDictionary(){#ifndef USE_NEW_SIMDICTIONARY   delete[] hashTable;#endif   Mutex::destroyMutex(mutex);}void SimNameDictionary::insert(SimObject* obj){   if (!obj || !obj->getName())      return;   SimObject* checkForDup = find(obj->getName());   if (checkForDup)      Con::warnf("Warning! You have a duplicate object name of %s. This can cause problems. You should rename one of them.", obj->getName());   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   if (!hashTable)   {      hashTable = new SimObject *[DefaultTableSize];      hashTableSize = DefaultTableSize;      hashEntryCount = 0;      dMemset(hashTable, 0, sizeof(*hashTable) * DefaultTableSize);   }   S32 idx = HashPointer(obj->getName()) % hashTableSize;   obj->nextNameObject = hashTable[idx];   hashTable[idx] = obj;   hashEntryCount++;   // Rehash if necessary.   if (hashEntryCount > hashTableSize)   {      // Allocate new table.      U32 newHashTableSize = hashTableSize * 2 + 1;      SimObject** newHashTable = new SimObject *[newHashTableSize];      dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);      // Move entries over.      for (U32 i = 0; i < hashTableSize; ++i)         for (SimObject* object = hashTable[i]; object != NULL; )         {            SimObject* next = object->nextNameObject;            idx = HashPointer(object->getName()) % newHashTableSize;            object->nextNameObject = newHashTable[idx];            newHashTable[idx] = object;            object = next;         }      // Switch tables.      delete[] hashTable;      hashTable = newHashTable;      hashTableSize = newHashTableSize;   }#else   root[obj->objectName] = obj;#endif   Mutex::unlockMutex(mutex);}SimObject* SimNameDictionary::find(StringTableEntry name){#ifndef USE_NEW_SIMDICTIONARY   // NULL is a valid lookup - it will always return NULL   if (!hashTable)      return NULL;   Mutex::lockMutex(mutex);   S32 idx = HashPointer(name) % hashTableSize;   SimObject *walk = hashTable[idx];   while (walk)   {      if (walk->getName() == name)      {         Mutex::unlockMutex(mutex);         return walk;      }      walk = walk->nextNameObject;   }   Mutex::unlockMutex(mutex);   return NULL;#else   Mutex::lockMutex(mutex);   StringDictDef::iterator it = root.find(name);   SimObject* f = (it == root.end() ? NULL : it->second);   Mutex::unlockMutex(mutex);   return f;#endif}void SimNameDictionary::remove(SimObject* obj){   if (!obj || !obj->getName())      return;   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];   while (*walk)   {      if (*walk == obj)      {         *walk = obj->nextNameObject;         obj->nextNameObject = nullptr;         hashEntryCount--;         Mutex::unlockMutex(mutex);         return;      }      walk = &((*walk)->nextNameObject);   }#else   const char* name = obj->objectName;   if (root.find(name) != root.end())      root.erase(name);#endif   Mutex::unlockMutex(mutex);}//----------------------------------------------------------------------------SimManagerNameDictionary::SimManagerNameDictionary(){#ifndef USE_NEW_SIMDICTIONARY   hashTable = new SimObject *[DefaultTableSize];   hashTableSize = DefaultTableSize;   hashEntryCount = 0;   dMemset(hashTable, 0, sizeof(hashTable[0]) * hashTableSize);#endif   mutex = Mutex::createMutex();}SimManagerNameDictionary::~SimManagerNameDictionary(){#ifndef USE_NEW_SIMDICTIONARY   delete[] hashTable;#endif   Mutex::destroyMutex(mutex);}void SimManagerNameDictionary::insert(SimObject* obj){   if (!obj || !obj->getName())      return;   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   S32 idx = HashPointer(obj->getName()) % hashTableSize;   obj->nextManagerNameObject = hashTable[idx];   hashTable[idx] = obj;   hashEntryCount++;   // Rehash if necessary.   if (hashEntryCount > hashTableSize)   {      // Allocate new table.      U32 newHashTableSize = hashTableSize * 2 + 1;      SimObject** newHashTable = new SimObject *[newHashTableSize];      dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);      // Move entries over.      for (U32 i = 0; i < hashTableSize; ++i)         for (SimObject* object = hashTable[i]; object != NULL; )         {            SimObject* next = object->nextManagerNameObject;            idx = HashPointer(object->getName()) % newHashTableSize;            object->nextManagerNameObject = newHashTable[idx];            newHashTable[idx] = object;            object = next;         }      // Switch tables.      delete[] hashTable;      hashTable = newHashTable;      hashTableSize = newHashTableSize;   }#else   root[obj->objectName] = obj;#endif   Mutex::unlockMutex(mutex);}SimObject* SimManagerNameDictionary::find(StringTableEntry name){   // NULL is a valid lookup - it will always return NULL   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   S32 idx = HashPointer(name) % hashTableSize;   SimObject *walk = hashTable[idx];   while (walk)   {      if (walk->getName() == name)      {         Mutex::unlockMutex(mutex);         return walk;      }      walk = walk->nextManagerNameObject;   }   Mutex::unlockMutex(mutex);   return NULL;#else   StringDictDef::iterator it = root.find(name);   SimObject* f = (it == root.end() ? NULL : it->second);   Mutex::unlockMutex(mutex);   return f;#endif}void SimManagerNameDictionary::remove(SimObject* obj){   if (!obj || !obj->getName())      return;#ifndef USE_NEW_SIMDICTIONARY   Mutex::lockMutex(mutex);   SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];   while (*walk)   {      if (*walk == obj)      {         *walk = obj->nextManagerNameObject;         obj->nextManagerNameObject = nullptr;         hashEntryCount--;         Mutex::unlockMutex(mutex);         return;      }      walk = &((*walk)->nextManagerNameObject);   }#else   StringTableEntry name = obj->objectName;   if (root.find(name) != root.end())      root.erase(name);#endif   Mutex::unlockMutex(mutex);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------SimIdDictionary::SimIdDictionary(){#ifndef USE_NEW_SIMDICTIONARY   dMemset(table, 0, sizeof(table[0]) * DefaultTableSize);#endif   mutex = Mutex::createMutex();}SimIdDictionary::~SimIdDictionary(){   Mutex::destroyMutex(mutex);}void SimIdDictionary::insert(SimObject* obj){   if (!obj)      return;   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   S32 idx = obj->getId() & TableBitMask;   obj->nextIdObject = table[idx];   AssertFatal(obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!");   table[idx] = obj;#else   root[obj->getId()] = obj;#endif   Mutex::unlockMutex(mutex);}SimObject* SimIdDictionary::find(S32 id){   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   S32 idx = id & TableBitMask;   SimObject *walk = table[idx];   while (walk)   {      if (walk->getId() == U32(id))      {         Mutex::unlockMutex(mutex);         return walk;      }      walk = walk->nextIdObject;   }   Mutex::unlockMutex(mutex);   return NULL;#else   SimObjectIdDictDef::iterator it = root.find(id);   SimObject* f = (it == root.end() ? NULL : it->second);   Mutex::unlockMutex(mutex);   return f;#endif}void SimIdDictionary::remove(SimObject* obj){   if (!obj)      return;   Mutex::lockMutex(mutex);#ifndef USE_NEW_SIMDICTIONARY   SimObject **walk = &table[obj->getId() & TableBitMask];   while (*walk && *walk != obj)      walk = &((*walk)->nextIdObject);   if (*walk)      *walk = obj->nextIdObject;#else   root.erase(obj->getId());#endif   Mutex::unlockMutex(mutex);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------
 |