diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index dac603517..03fadb990 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -29,19 +29,23 @@ extern U32 HashPointer(StringTableEntry e); SimNameDictionary::SimNameDictionary() { +#ifndef USE_NEW_SIMDICTIONARY hashTable = NULL; +#endif mutex = Mutex::createMutex(); } SimNameDictionary::~SimNameDictionary() { +#ifndef USE_NEW_SIMDICTIONARY delete[] hashTable; +#endif Mutex::destroyMutex(mutex); } void SimNameDictionary::insert(SimObject* obj) { - if(!obj->objectName) + if(!obj || !obj->objectName) return; SimObject* checkForDup = find(obj->objectName); @@ -50,7 +54,7 @@ void SimNameDictionary::insert(SimObject* obj) Con::warnf("Warning! You have a duplicate datablock name of %s. This can cause problems. You should rename one of them.", obj->objectName); Mutex::lockMutex(mutex); - +#ifndef USE_NEW_SIMDICTIONARY if(!hashTable) { hashTable = new SimObject *[DefaultTableSize]; @@ -95,12 +99,15 @@ void SimNameDictionary::insert(SimObject* obj) 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; @@ -121,15 +128,22 @@ SimObject* SimNameDictionary::find(StringTableEntry name) 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->objectName) + if(!obj || !obj->objectName) return; Mutex::lockMutex(mutex); - +#ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; while(*walk) { @@ -144,7 +158,11 @@ void SimNameDictionary::remove(SimObject* obj) } walk = &((*walk)->nextNameObject); } - +#else + const char* name = obj->objectName; + if (root.find(name) != root.end()) + root.erase(name); +#endif Mutex::unlockMutex(mutex); } @@ -152,28 +170,31 @@ void SimNameDictionary::remove(SimObject* obj) 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->objectName) + if(!obj || !obj->objectName) return; Mutex::lockMutex(mutex); - +#ifndef USE_NEW_SIMDICTIONARY S32 idx = HashPointer(obj->objectName) % hashTableSize; obj->nextManagerNameObject = hashTable[idx]; hashTable[idx] = obj; @@ -209,7 +230,9 @@ void SimManagerNameDictionary::insert(SimObject* obj) hashTable = newHashTable; hashTableSize = newHashTableSize; } - +#else + root[obj->objectName] = obj; +#endif Mutex::unlockMutex(mutex); } @@ -219,6 +242,7 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) Mutex::lockMutex(mutex); +#ifndef USE_NEW_SIMDICTIONARY S32 idx = HashPointer(name) % hashTableSize; SimObject *walk = hashTable[idx]; while(walk) @@ -230,16 +254,23 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) } 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->objectName) + if(!obj || !obj->objectName) return; +#ifndef USE_NEW_SIMDICTIONARY Mutex::lockMutex(mutex); SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; @@ -256,7 +287,11 @@ void SimManagerNameDictionary::remove(SimObject* obj) } walk = &((*walk)->nextManagerNameObject); } - +#else + StringTableEntry name = obj->objectName; + if (root.find(name) != root.end()) + root.erase(name); +#endif Mutex::unlockMutex(mutex); } @@ -265,7 +300,9 @@ void SimManagerNameDictionary::remove(SimObject* obj) SimIdDictionary::SimIdDictionary() { +#ifndef USE_NEW_SIMDICTIONARY dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize ); +#endif mutex = Mutex::createMutex(); } @@ -274,22 +311,29 @@ SimIdDictionary::~SimIdDictionary() Mutex::destroyMutex(mutex); } + + void SimIdDictionary::insert(SimObject* obj) { - Mutex::lockMutex(mutex); + 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) @@ -301,22 +345,32 @@ SimObject* SimIdDictionary::find(S32 id) } 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) { - Mutex::lockMutex(mutex); + 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); } diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index 75fc075e2..bbfb0f385 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -33,8 +33,38 @@ #include "platform/threads/mutex.h" #endif +#include "torqueConfig.h" + class SimObject; +#ifdef USE_NEW_SIMDICTIONARY +#include +#include + +#ifndef _SIM_H_ +#include "console/sim.h" +#endif + +struct StringTableEntryHash +{ + inline size_t operator()(StringTableEntry val) const + { + return (size_t)val; + } +}; + +struct StringTableEntryEq +{ + inline bool operator()(StringTableEntry s1, StringTableEntry s2) const + { + return s1 == s2; + } +}; + +typedef std::unordered_map StringDictDef; +typedef std::unordered_map SimObjectIdDictDef; +#endif + //---------------------------------------------------------------------------- /// Map of names to SimObjects /// @@ -42,6 +72,7 @@ class SimObject; /// for fast removal of an object given object* class SimNameDictionary { +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -50,6 +81,9 @@ class SimNameDictionary SimObject **hashTable; // hash the pointers of the names... S32 hashTableSize; S32 hashEntryCount; +#else + StringDictDef root; +#endif void *mutex; @@ -64,6 +98,7 @@ public: class SimManagerNameDictionary { +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 29 @@ -72,6 +107,9 @@ class SimManagerNameDictionary SimObject **hashTable; // hash the pointers of the names... S32 hashTableSize; S32 hashEntryCount; +#else + StringDictDef root; +#endif void *mutex; @@ -91,12 +129,16 @@ public: /// for fast removal of an object given object* class SimIdDictionary { +#ifndef USE_NEW_SIMDICTIONARY enum { DefaultTableSize = 4096, TableBitMask = 4095 }; SimObject *table[DefaultTableSize]; +#else + SimObjectIdDictDef root; +#endif void *mutex; diff --git a/Templates/Empty/source/torqueConfig.h b/Templates/Empty/source/torqueConfig.h index b1c01a49b..5903ef1a5 100644 --- a/Templates/Empty/source/torqueConfig.h +++ b/Templates/Empty/source/torqueConfig.h @@ -52,6 +52,11 @@ #define TORQUE_DISABLE_MEMORY_MANAGER #endif +/// The improved SimDictionary uses C++11 and is designed for games where +/// there are over 10000 simobjects active normally. To enable the new +/// SimDictionary just uncomment the line below. +//#define USE_NEW_SIMDICTIONARY + /// Define me if you want to disable the virtual mount system. //#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM diff --git a/Templates/Full/source/torqueConfig.h b/Templates/Full/source/torqueConfig.h index 52b506fb6..474799208 100644 --- a/Templates/Full/source/torqueConfig.h +++ b/Templates/Full/source/torqueConfig.h @@ -52,6 +52,11 @@ #define TORQUE_DISABLE_MEMORY_MANAGER #endif +/// The improved SimDictionary uses C++11 and is designed for games where +/// there are over 10000 simobjects active normally. To enable the new +/// SimDictionary just uncomment the line below. +//#define USE_NEW_SIMDICTIONARY + /// Define me if you want to disable the virtual mount system. //#define TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM