diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp index 8cbdd700c7..ed4cb9b85f 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp +++ b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp @@ -201,6 +201,16 @@ bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange return foundKey != nullptr; } +void plRegistryKeyList::PrepForWrite() +{ + uint32_t objectID = 1; + for (plKeyImp* key : fKeys) { + if (key->ObjectIsLoaded()) { + key->SetObjectID(objectID++); + } + } +} + void plRegistryKeyList::Read(hsStream* s) { uint32_t keyListLen = s->ReadLE32(); diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h index 6e71efa7ab..21fac7a019 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h +++ b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h @@ -97,6 +97,10 @@ class plRegistryKeyList void SetKeyUsed(plKeyImp* key) { ++fReffedKeys; } bool SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange); + // Export time only. Before we write to disk, assign all the loaded keys + // sequential object IDs that they can use to do fast lookups at load time. + void PrepForWrite(); + void Read(hsStream* s); void Write(hsStream* s); }; diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp index 15f79c1072..1ff9f75795 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp +++ b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp @@ -204,6 +204,15 @@ void plRegistryPageNode::UnloadKeys() fLoadedTypes = 0; } +void plRegistryPageNode::PrepForWrite() +{ + if (!fIsNewPage) + return; + + for (auto [idx, keyList] : fKeyLists) + keyList->PrepForWrite(); +} + //// plWriteIterator ///////////////////////////////////////////////////////// // Key iterator for writing objects class plWriteIterator : public plRegistryKeyIterator diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h index de466b37ed..39acf7433a 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h +++ b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h @@ -139,6 +139,10 @@ class plRegistryPageNode hsStream* OpenStream(); void CloseStream(); + // Export time only. Before we write to disk, assign all the loaded keys + // sequential object IDs that they can use to do fast lookups at load time. + void PrepForWrite(); + // Takes care of everything involved in writing this page to disk void Write(); void DeleteSource(); diff --git a/Sources/Tools/MaxMain/plPluginResManager.cpp b/Sources/Tools/MaxMain/plPluginResManager.cpp index 06eaf680d1..3693c02726 100644 --- a/Sources/Tools/MaxMain/plPluginResManager.cpp +++ b/Sources/Tools/MaxMain/plPluginResManager.cpp @@ -373,6 +373,18 @@ plLocation plPluginResManager::ICreateLocation(const ST::string& age, const ST:: return newLoc; } +class plObjectIDSortingPageIterator : public plRegistryPageIterator +{ +public: + plObjectIDSortingPageIterator() {} + bool EatPage(plRegistryPageNode *page) override + { + if (page->GetPageInfo().GetLocation() != plLocation::kGlobalFixedLoc) + page->PrepForWrite(); + return true; + } +}; + class plWritePageIterator : public plRegistryPageIterator { public: @@ -387,6 +399,9 @@ class plWritePageIterator : public plRegistryPageIterator void plPluginResManager::WriteAllPages() { + plObjectIDSortingPageIterator idSort; + IteratePages(&idSort); + plWritePageIterator iter; IteratePages(&iter); }