Browse Source

Fix #365

plRegistryKeyList::Read assumed that plUoid object IDs are always
sequential. This is not the case since f664e8b resulted in all keys
getting an ID. The problem manifested itself here because there were
temporary materials that were being created and thrown away, causing
object ID gaps.
Adam Johnson 11 years ago
parent
commit
e48a4767cf
  1. 20
      Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp

20
Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp

@ -52,7 +52,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
plRegistryKeyList::~plRegistryKeyList() plRegistryKeyList::~plRegistryKeyList()
{ {
std::for_each(fKeys.begin(), fKeys.end(), std::for_each(fKeys.begin(), fKeys.end(),
[] (plKeyImp* key) { if (!key->ObjectIsLoaded()) delete key; } [] (plKeyImp* key) { if (key && !key->ObjectIsLoaded()) delete key; }
); );
} }
@ -85,7 +85,7 @@ plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid) const
// because of local data. Verify that we have the right key by // because of local data. Verify that we have the right key by
// name, and if it's wrong, do the slower find-by-name. // name, and if it's wrong, do the slower find-by-name.
plKeyImp *keyImp = fKeys[objectID-1]; plKeyImp *keyImp = fKeys[objectID-1];
if (keyImp->GetName().CompareI(uoid.GetObjectName()) != 0) if (!keyImp || keyImp->GetName().CompareI(uoid.GetObjectName()) != 0)
return FindKey(uoid.GetObjectName()); return FindKey(uoid.GetObjectName());
else else
return keyImp; return keyImp;
@ -172,8 +172,9 @@ bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange
// Recall that vectors are index zero but normal object IDs are index one... // Recall that vectors are index zero but normal object IDs are index one...
else if (id <= fKeys.size()) { else if (id <= fKeys.size()) {
if (fKeys[id-1]->GetUoid().GetObjectID() == id) plKeyImp* tempKey = fKeys[id-1];
foundKey = fKeys[id-1]; if (tempKey && tempKey->GetUoid().GetObjectID() == id)
foundKey = tempKey;
} }
// Last chance: do a slow name search for that key. // Last chance: do a slow name search for that key.
@ -203,14 +204,19 @@ void plRegistryKeyList::Read(hsStream* s)
s->ReadByte(); s->ReadByte();
uint32_t numKeys = s->ReadLE32(); uint32_t numKeys = s->ReadLE32();
fKeys.reserve(numKeys); fKeys.reserve((numKeys * 3) / 2);
for (uint32_t i = 0; i < numKeys; ++i) for (uint32_t i = 0; i < numKeys; ++i)
{ {
plKeyImp* newKey = new plKeyImp; plKeyImp* newKey = new plKeyImp;
newKey->Read(s); newKey->Read(s);
fKeys.push_back(newKey);
uint32_t id = newKey->GetUoid().GetObjectID();
if (fKeys.size() < id)
fKeys.resize(id);
fKeys[id - 1] = newKey;
} }
fKeys.shrink_to_fit();
} }
void plRegistryKeyList::Write(hsStream* s) void plRegistryKeyList::Write(hsStream* s)
@ -229,7 +235,7 @@ void plRegistryKeyList::Write(hsStream* s)
for (auto it = fKeys.begin(); it != fKeys.end(); ++it) for (auto it = fKeys.begin(); it != fKeys.end(); ++it)
{ {
plKeyImp* key = *it; plKeyImp* key = *it;
if (key->ObjectIsLoaded()) if (key && key->ObjectIsLoaded())
{ {
++keyCount; ++keyCount;
key->Write(s); key->Write(s);

Loading…
Cancel
Save