diff --git a/src/game/data/static/puzzle.dat b/src/game/data/static/puzzle.dat index bab034a..41bdabf 100644 Binary files a/src/game/data/static/puzzle.dat and b/src/game/data/static/puzzle.dat differ diff --git a/src/game/data/static/uiconfig.dat b/src/game/data/static/uiconfig.dat index db36b07..f62b36f 100644 Binary files a/src/game/data/static/uiconfig.dat and b/src/game/data/static/uiconfig.dat differ diff --git a/src/game/util/HashMap.h b/src/game/util/HashMap.h new file mode 100644 index 0000000..0c58670 --- /dev/null +++ b/src/game/util/HashMap.h @@ -0,0 +1,91 @@ +#include "bx/hash.h" +#include +#include + +template struct HashMapInsertResult +{ + T& Obj = nullptr; + bool ElementExists = false; +}; + +template struct HashMapInsertResultConst +{ + const T& Obj = nullptr; + bool ElementExists = false; +}; + +// BitSize 16 will make the HashTable ~200kb with 65k entries +template struct HashMapCore +{ + static constexpr uint32_t SlotCount = (1 << BitSize); + static constexpr uint32_t RequiredDataSize = SlotCount * sizeof(T); + + T* Data = nullptr; + uint32_t HashTable[SlotCount]{0}; + + // External array that should be RequiredDataSize bytes big + void Init(T* data, uint64_t dataSize) + { + Data = data; + assert(data != nullptr); + assert(dataSize == RequiredDataSize); + } + + bool Has(uint32_t hash) const + { + return HashTable[FindIdx(hash)] == hash; + } + + HashMapInsertResult Get(uint32_t hash) + { + uint16_t idx = FindIdx(hash); + return {Data[idx], HashTable[idx] == hash}; + } + + const T& Get(uint32_t hash) const + { + uint16_t idx = FindIdx(hash); + return {Data[idx], HashTable[idx] == hash}; + } + + bool Remove(uint32_t hash); // TODO: requires tombstones so later entries survive + + private: + uint16_t FindIdx(uint32_t hash) const + { + uint32_t mask = SlotCount - 1; + uint32_t idx = hash & mask; + uint32_t tableEntry = HashTable[idx]; + uint32_t stepCount = 0; + while (tableEntry != hash && tableEntry != 0 && stepCount < UINT16_MAX) + { + idx = (idx + 1) % SlotCount; + tableEntry = HashTable[idx]; + ++stepCount; + } + assert(stepCount < UINT16_MAX); + return idx; + } +}; + +namespace HashMapTests +{ + struct AAA + { + int X = 3; + int Y = 42; + }; + + inline void Test() + { + HashMapCore testMap; + AAA* backingData = new AAA[testMap.RequiredDataSize](); + testMap.Init(backingData, testMap.RequiredDataSize); + AAA test{}; + AAA test2{5, 6}; + testMap.Get(bx::hash(test)).Obj = test; + testMap.Get(bx::hash(test2)).Obj = test2; + delete[] backingData; + } + +} // namespace HashMapTests diff --git a/tools/minidef.exe b/tools/minidef.exe index 757f646..a6156c2 100644 --- a/tools/minidef.exe +++ b/tools/minidef.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e101b18da1ba1e37156b03bc19ba3ee488d6eb02acbf491063f1d1f56dddaad +oid sha256:8f183d74c5423fd3920916186d2065ea9b7373b6c4a0843f1802a35ed97fc8a1 size 167424