Torque3D/Engine/source/console/simDictionary.cpp

382 lines
9.7 KiB
C++
Raw Normal View History

2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// 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"
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
2014-09-14 18:44:07 +00:00
extern U32 HashPointer(StringTableEntry e);
2012-09-19 15:15:01 +00:00
SimNameDictionary::SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
hashTable = NULL;
2020-05-11 19:40:31 +00:00
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimNameDictionary::~SimNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
delete[] hashTable;
#endif
2012-09-19 15:15:01 +00:00
Mutex::destroyMutex(mutex);
}
void SimNameDictionary::insert(SimObject* obj)
{
if (!obj || !obj->getName())
2012-09-19 15:15:01 +00:00
return;
SimObject* checkForDup = find(obj->getName());
2012-09-19 15:15:01 +00:00
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());
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2017-11-06 04:33:32 +00:00
if (!hashTable)
2012-09-19 15:15:01 +00:00
{
hashTable = new SimObject *[DefaultTableSize];
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
2017-11-06 04:33:32 +00:00
dMemset(hashTable, 0, sizeof(*hashTable) * DefaultTableSize);
2012-09-19 15:15:01 +00:00
}
2017-11-06 04:33:32 +00:00
S32 idx = HashPointer(obj->getName()) % hashTableSize;
2012-09-19 15:15:01 +00:00
obj->nextNameObject = hashTable[idx];
hashTable[idx] = obj;
hashEntryCount++;
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
// Rehash if necessary.
2017-11-06 04:33:32 +00:00
if (hashEntryCount > hashTableSize)
2012-09-19 15:15:01 +00:00
{
// Allocate new table.
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
U32 newHashTableSize = hashTableSize * 2 + 1;
2017-11-06 04:33:32 +00:00
SimObject** newHashTable = new SimObject *[newHashTableSize];
dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);
2012-09-19 15:15:01 +00:00
// Move entries over.
2017-11-06 04:33:32 +00:00
for (U32 i = 0; i < hashTableSize; ++i)
for (SimObject* object = hashTable[i]; object != NULL; )
2012-09-19 15:15:01 +00:00
{
SimObject* next = object->nextNameObject;
idx = HashPointer(object->getName()) % newHashTableSize;
2017-11-06 04:33:32 +00:00
object->nextNameObject = newHashTable[idx];
newHashTable[idx] = object;
2012-09-19 15:15:01 +00:00
object = next;
}
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
// Switch tables.
2017-11-06 04:33:32 +00:00
delete[] hashTable;
2012-09-19 15:15:01 +00:00
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
SimObject* SimNameDictionary::find(StringTableEntry name)
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
// NULL is a valid lookup - it will always return NULL
2017-11-06 04:33:32 +00:00
if (!hashTable)
2012-09-19 15:15:01 +00:00
return NULL;
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
S32 idx = HashPointer(name) % hashTableSize;
SimObject *walk = hashTable[idx];
2017-11-06 04:33:32 +00:00
while (walk)
2012-09-19 15:15:01 +00:00
{
if (walk->getName() == name)
2012-09-19 15:15:01 +00:00
{
Mutex::unlockMutex(mutex);
return walk;
}
walk = walk->nextNameObject;
}
Mutex::unlockMutex(mutex);
return NULL;
#else
2017-11-06 04:33:32 +00:00
Mutex::lockMutex(mutex);
StringDictDef::iterator it = root.find(name);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
2012-09-19 15:15:01 +00:00
}
void SimNameDictionary::remove(SimObject* obj)
{
if (!obj || !obj->getName())
2012-09-19 15:15:01 +00:00
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];
2017-11-06 04:33:32 +00:00
while (*walk)
2012-09-19 15:15:01 +00:00
{
2017-11-06 04:33:32 +00:00
if (*walk == obj)
2012-09-19 15:15:01 +00:00
{
*walk = obj->nextNameObject;
obj->nextNameObject = NULL;
2012-09-19 15:15:01 +00:00
hashEntryCount--;
Mutex::unlockMutex(mutex);
return;
}
walk = &((*walk)->nextNameObject);
}
#else
const char* name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
2017-11-06 04:33:32 +00:00
}
2012-09-19 15:15:01 +00:00
//----------------------------------------------------------------------------
SimManagerNameDictionary::SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
hashTable = new SimObject *[DefaultTableSize];
hashTableSize = DefaultTableSize;
hashEntryCount = 0;
2017-11-06 04:33:32 +00:00
dMemset(hashTable, 0, sizeof(hashTable[0]) * hashTableSize);
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimManagerNameDictionary::~SimManagerNameDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
delete[] hashTable;
#endif
2012-09-19 15:15:01 +00:00
Mutex::destroyMutex(mutex);
}
void SimManagerNameDictionary::insert(SimObject* obj)
{
if (!obj || !obj->getName())
2012-09-19 15:15:01 +00:00
return;
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
S32 idx = HashPointer(obj->getName()) % hashTableSize;
2012-09-19 15:15:01 +00:00
obj->nextManagerNameObject = hashTable[idx];
hashTable[idx] = obj;
hashEntryCount++;
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
// Rehash if necessary.
2017-11-06 04:33:32 +00:00
if (hashEntryCount > hashTableSize)
2012-09-19 15:15:01 +00:00
{
// Allocate new table.
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
U32 newHashTableSize = hashTableSize * 2 + 1;
2017-11-06 04:33:32 +00:00
SimObject** newHashTable = new SimObject *[newHashTableSize];
dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize);
2012-09-19 15:15:01 +00:00
// Move entries over.
2017-11-06 04:33:32 +00:00
for (U32 i = 0; i < hashTableSize; ++i)
for (SimObject* object = hashTable[i]; object != NULL; )
2012-09-19 15:15:01 +00:00
{
SimObject* next = object->nextManagerNameObject;
idx = HashPointer(object->getName()) % newHashTableSize;
2017-11-06 04:33:32 +00:00
object->nextManagerNameObject = newHashTable[idx];
newHashTable[idx] = object;
2012-09-19 15:15:01 +00:00
object = next;
}
2017-11-06 04:33:32 +00:00
2012-09-19 15:15:01 +00:00
// Switch tables.
2017-11-06 04:33:32 +00:00
delete[] hashTable;
2012-09-19 15:15:01 +00:00
hashTable = newHashTable;
hashTableSize = newHashTableSize;
}
#else
root[obj->objectName] = obj;
#endif
2012-09-19 15:15:01 +00:00
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
2012-09-19 15:15:01 +00:00
S32 idx = HashPointer(name) % hashTableSize;
SimObject *walk = hashTable[idx];
2017-11-06 04:33:32 +00:00
while (walk)
2012-09-19 15:15:01 +00:00
{
if (walk->getName() == name)
2012-09-19 15:15:01 +00:00
{
Mutex::unlockMutex(mutex);
return walk;
}
walk = walk->nextManagerNameObject;
}
Mutex::unlockMutex(mutex);
2012-09-19 15:15:01 +00:00
return NULL;
#else
StringDictDef::iterator it = root.find(name);
SimObject* f = (it == root.end() ? NULL : it->second);
Mutex::unlockMutex(mutex);
return f;
#endif
2012-09-19 15:15:01 +00:00
}
void SimManagerNameDictionary::remove(SimObject* obj)
{
if (!obj || !obj->getName())
2012-09-19 15:15:01 +00:00
return;
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
SimObject **walk = &hashTable[HashPointer(obj->getName()) % hashTableSize];
2017-11-06 04:33:32 +00:00
while (*walk)
2012-09-19 15:15:01 +00:00
{
2017-11-06 04:33:32 +00:00
if (*walk == obj)
2012-09-19 15:15:01 +00:00
{
*walk = obj->nextManagerNameObject;
obj->nextManagerNameObject = NULL;
2012-09-19 15:15:01 +00:00
hashEntryCount--;
Mutex::unlockMutex(mutex);
return;
}
walk = &((*walk)->nextManagerNameObject);
}
#else
StringTableEntry name = obj->objectName;
if (root.find(name) != root.end())
root.erase(name);
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
2017-11-06 04:33:32 +00:00
}
2012-09-19 15:15:01 +00:00
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
SimIdDictionary::SimIdDictionary()
{
#ifndef USE_NEW_SIMDICTIONARY
2017-11-06 04:33:32 +00:00
dMemset(table, 0, sizeof(table[0]) * DefaultTableSize);
#endif
2012-09-19 15:15:01 +00:00
mutex = Mutex::createMutex();
}
SimIdDictionary::~SimIdDictionary()
{
Mutex::destroyMutex(mutex);
}
2012-09-19 15:15:01 +00:00
void SimIdDictionary::insert(SimObject* obj)
{
if (!obj)
return;
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
S32 idx = obj->getId() & TableBitMask;
obj->nextIdObject = table[idx];
2017-11-06 04:33:32 +00:00
AssertFatal(obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!");
2012-09-19 15:15:01 +00:00
table[idx] = obj;
#else
root[obj->getId()] = obj;
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
SimObject* SimIdDictionary::find(S32 id)
{
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
S32 idx = id & TableBitMask;
SimObject *walk = table[idx];
2017-11-06 04:33:32 +00:00
while (walk)
2012-09-19 15:15:01 +00:00
{
2017-11-06 04:33:32 +00:00
if (walk->getId() == U32(id))
2012-09-19 15:15:01 +00:00
{
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
2012-09-19 15:15:01 +00:00
}
void SimIdDictionary::remove(SimObject* obj)
{
if (!obj)
return;
2012-09-19 15:15:01 +00:00
Mutex::lockMutex(mutex);
#ifndef USE_NEW_SIMDICTIONARY
2012-09-19 15:15:01 +00:00
SimObject **walk = &table[obj->getId() & TableBitMask];
2017-11-06 04:33:32 +00:00
while (*walk && *walk != obj)
2012-09-19 15:15:01 +00:00
walk = &((*walk)->nextIdObject);
2017-11-06 04:33:32 +00:00
if (*walk)
2012-09-19 15:15:01 +00:00
*walk = obj->nextIdObject;
#else
root.erase(obj->getId());
#endif
2012-09-19 15:15:01 +00:00
Mutex::unlockMutex(mutex);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------