I'm in the process of developing a game engine and I would like to refer to game objects and assets by an integer id rather than by their string name. This should avoid any string comparisons at runtime. As a result I'm trying to implement the string hashing approach that Jason Gregory describes in Game Engine Architecture.
I've got the actual hashing working, using FNV-1a in my case, but there are some parts of the design from the book that I don't understand.
static StringId sid_foo = internString("foo");
static StringId sid_bar = internString("bar");
...
[stringid.h]
typedef U32 StringId;
extern StringId internString(const char* str);
[stringid.cpp]
static HashTable<StringId, const char*> gStringIdTable;
StringId internString(const char* str)
{
StringId sid = hashCrc32(str);
HashTable<StringId, const char*>::iterator it
= gStringIdTable.find(sid);
if (it == gStringTable.end())
{
// This string has not yet been added to the
// table. Add it, being sure to copy it in case
// the original was dynamically allocated and
// might later be freed.
gStringTable[sid] = strdup(str);
}
return sid;
}
- Presumably HashTable is a custom hash table implementation as no such class exists in C++? Is there any problem with my current setup of storing the hashed strings in a
std::unordered_map<StringID, const char*>
? - From my research, making the hash table static means that it is only accessible inside this translation unit. a) Why is it defined this way, and how would you then access the hash table in the rest of the game engine? b) Or do you call
internString
for every string and store the returned hash in a header #included in every file that needs access? - What is the purpose of making
externString
extern
?
Thanks.
static
can affect linkage, it also means that only a single instance is instantiated & its duration lasts for the entire program. Hard to know w/out see how it's being used, but I suspect that is declaredstatic
in order to make it act like a global. \$\endgroup\$ – Pikalek Dec 15 '20 at 0:30