mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 19:29:09 +00:00
@ -107,6 +107,10 @@ plKey hsKeyedObject::RegisterAs(plFixedKeyId fixedKey)
|
|||||||
if (key == nil)
|
if (key == nil)
|
||||||
{
|
{
|
||||||
key = hsgResMgr::ResMgr()->NewKey(meUoid, this);
|
key = hsgResMgr::ResMgr()->NewKey(meUoid, this);
|
||||||
|
|
||||||
|
// the key list "helpfully" assigns us an object id.
|
||||||
|
// we don't want one for fixed keys however (initialization order might bite us in the ass)
|
||||||
|
static_cast<plKeyImp*>(key)->SetObjectID(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -438,15 +438,9 @@ plKey plKeyFinder::IFindSceneNodeKey(plRegistryPageNode* page) const
|
|||||||
plRegistryKeyList* keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
plRegistryKeyList* keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||||
if (keyList)
|
if (keyList)
|
||||||
{
|
{
|
||||||
if (keyList->fStaticKeys.size() == 1)
|
if (keyList->fKeys.size() == 1)
|
||||||
{
|
{
|
||||||
return plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
return plKey::Make((plKeyData*)keyList->fKeys[0]);
|
||||||
}
|
|
||||||
else if (keyList->fDynamicKeys.size() == 1) // happens during export
|
|
||||||
{
|
|
||||||
plRegistryKeyList::DynSet::const_iterator it = keyList->fDynamicKeys.begin();
|
|
||||||
plKeyImp* keyImp = *it;
|
|
||||||
return plKey::Make(keyImp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,9 +453,9 @@ plKey plKeyFinder::IFindSceneNodeKey(plRegistryPageNode* page) const
|
|||||||
// Get the list of all sceneNodes
|
// Get the list of all sceneNodes
|
||||||
plKey retVal(nil);
|
plKey retVal(nil);
|
||||||
keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
keyList = page->IGetKeyList(CLASS_INDEX_SCOPED(plSceneNode));
|
||||||
if (keyList && keyList->fStaticKeys.size() == 1)
|
if (keyList && keyList->fKeys.size() == 1)
|
||||||
{
|
{
|
||||||
retVal = plKey::Make((plKeyData*)keyList->fStaticKeys[0]);
|
retVal = plKey::Make((plKeyData*)keyList->fKeys[0]);
|
||||||
}
|
}
|
||||||
// If we just loaded up all the keys for this page, then we
|
// If we just loaded up all the keys for this page, then we
|
||||||
// may have a bunch of keys with a refcount of 0. For any of
|
// may have a bunch of keys with a refcount of 0. For any of
|
||||||
|
@ -39,83 +39,44 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
Mead, WA 99021
|
Mead, WA 99021
|
||||||
|
|
||||||
*==LICENSE==*/
|
*==LICENSE==*/
|
||||||
#include "plRegistryKeyList.h"
|
|
||||||
#include "plRegistryHelpers.h"
|
|
||||||
#include "hsStream.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
plRegistryKeyList::plRegistryKeyList(uint16_t classType)
|
#include "HeadSpin.h"
|
||||||
{
|
#include "hsStream.h"
|
||||||
fClassType = classType;
|
|
||||||
fReffedStaticKeys = 0;
|
#include "pnKeyedObject/plKeyImp.h"
|
||||||
fLocked = 0;
|
#include "plRegistryHelpers.h"
|
||||||
fFlags = 0;
|
#include "plRegistryKeyList.h"
|
||||||
}
|
|
||||||
|
|
||||||
plRegistryKeyList::~plRegistryKeyList()
|
plRegistryKeyList::~plRegistryKeyList()
|
||||||
{
|
{
|
||||||
hsAssert(fLocked == 0, "Key list still locked on delete");
|
std::for_each(fKeys.begin(), fKeys.end(),
|
||||||
|
[] (plKeyImp* key) { if (!key->ObjectIsLoaded()) delete key; }
|
||||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
);
|
||||||
{
|
|
||||||
plKeyImp* keyImp = fStaticKeys[i];
|
|
||||||
if (!keyImp->ObjectIsLoaded())
|
|
||||||
delete keyImp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special dummy key that lets us set the return value of the GetName call.
|
plKeyImp* plRegistryKeyList::FindKey(const plString& keyName) const
|
||||||
// Makes it easier to do STL searches.
|
|
||||||
class plSearchKeyImp : public plKeyImp
|
|
||||||
{
|
{
|
||||||
public:
|
auto it = std::find_if(fKeys.begin(), fKeys.end(),
|
||||||
plString fSearchKeyName;
|
[&] (plKeyImp* key) { return key->GetName().CompareI(keyName) == 0; }
|
||||||
const plString& GetName() const { return fSearchKeyName; }
|
);
|
||||||
};
|
if (it != fKeys.end())
|
||||||
|
return *it;
|
||||||
plKeyImp* plRegistryKeyList::FindKey(const plString& keyName)
|
|
||||||
{
|
|
||||||
static plSearchKeyImp searchKey;
|
|
||||||
searchKey.fSearchKeyName = keyName;
|
|
||||||
|
|
||||||
// Search the static key list
|
|
||||||
if (fFlags & kStaticUnsorted)
|
|
||||||
{
|
|
||||||
// We're unsorted, brute force it. May do a separate search table in the
|
|
||||||
// future if this is a bottlneck
|
|
||||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
|
||||||
{
|
|
||||||
plKeyImp* curKey = fStaticKeys[i];
|
|
||||||
if (curKey && !keyName.Compare(curKey->GetName(), plString::kCaseInsensitive))
|
|
||||||
return curKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return nullptr;
|
||||||
// We're sorted, do a fast lookup
|
|
||||||
StaticVec::const_iterator it = std::lower_bound(fStaticKeys.begin(), fStaticKeys.end(), &searchKey, KeySorter());
|
|
||||||
if (it != fStaticKeys.end() && !keyName.Compare((*it)->GetName(), plString::kCaseInsensitive))
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search the dynamic key list
|
|
||||||
DynSet::const_iterator dynIt = fDynamicKeys.find(&searchKey);
|
|
||||||
if (dynIt != fDynamicKeys.end())
|
|
||||||
return *dynIt;
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid)
|
plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid) const
|
||||||
{
|
{
|
||||||
uint32_t objectID = uoid.GetObjectID();
|
uint32_t objectID = uoid.GetObjectID();
|
||||||
|
|
||||||
// Key is dynamic or doesn't know it's index. Do a find by name.
|
// Key is dynamic or doesn't know its index. Do a find by name.
|
||||||
if (objectID == 0)
|
if (objectID == 0)
|
||||||
return FindKey(uoid.GetObjectName());
|
return FindKey(uoid.GetObjectName());
|
||||||
|
|
||||||
// Direct lookup
|
// Direct lookup
|
||||||
if (objectID <= fStaticKeys.size())
|
if (objectID <= fKeys.size())
|
||||||
{
|
{
|
||||||
#ifdef PLASMA_EXTERNAL_RELEASE
|
#ifdef PLASMA_EXTERNAL_RELEASE
|
||||||
return fStaticKeys[objectID-1];
|
return fStaticKeys[objectID-1];
|
||||||
@ -123,8 +84,8 @@ plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid)
|
|||||||
// If this is an internal release, our objectIDs might not match
|
// If this is an internal release, our objectIDs might not match
|
||||||
// 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 = fStaticKeys[objectID-1];
|
plKeyImp *keyImp = fKeys[objectID-1];
|
||||||
if (keyImp->GetName().Compare(uoid.GetObjectName(), plString::kCaseInsensitive) != 0)
|
if (keyImp->GetName().CompareI(uoid.GetObjectName()) != 0)
|
||||||
return FindKey(uoid.GetObjectName());
|
return FindKey(uoid.GetObjectName());
|
||||||
else
|
else
|
||||||
return keyImp;
|
return keyImp;
|
||||||
@ -135,29 +96,17 @@ plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid)
|
|||||||
// because no one was using them. No worries. The resManager will catch this and
|
// because no one was using them. No worries. The resManager will catch this and
|
||||||
// reload our keys, then try again.
|
// reload our keys, then try again.
|
||||||
|
|
||||||
return nil;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
void plRegistryKeyList::ILock()
|
|
||||||
{
|
|
||||||
fLocked++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void plRegistryKeyList::IUnlock()
|
|
||||||
{
|
|
||||||
fLocked--;
|
|
||||||
if (fLocked == 0)
|
|
||||||
IRepack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool plRegistryKeyList::IterateKeys(plRegistryKeyIterator* iterator)
|
bool plRegistryKeyList::IterateKeys(plRegistryKeyIterator* iterator)
|
||||||
{
|
{
|
||||||
ILock();
|
ILock();
|
||||||
|
|
||||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
for (auto it = fKeys.begin(); it != fKeys.end(); ++it)
|
||||||
{
|
{
|
||||||
plKeyImp* keyImp = fStaticKeys[i];
|
plKeyImp* keyImp = *it;
|
||||||
if (keyImp != nil)
|
if (keyImp)
|
||||||
{
|
{
|
||||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
if (!iterator->EatKey(plKey::Make(keyImp)))
|
||||||
{
|
{
|
||||||
@ -167,18 +116,6 @@ bool plRegistryKeyList::IterateKeys(plRegistryKeyIterator* iterator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DynSet::const_iterator it;
|
|
||||||
for (it = fDynamicKeys.begin(); it != fDynamicKeys.end(); it++)
|
|
||||||
{
|
|
||||||
plKeyImp* keyImp = *it;
|
|
||||||
hsAssert(keyImp, "Shouldn't ever have a nil dynamic key");
|
|
||||||
if (!iterator->EatKey(plKey::Make(keyImp)))
|
|
||||||
{
|
|
||||||
IUnlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IUnlock();
|
IUnlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -188,25 +125,32 @@ void plRegistryKeyList::AddKey(plKeyImp* key, LoadStatus& loadStatusChange)
|
|||||||
loadStatusChange = kNoChange;
|
loadStatusChange = kNoChange;
|
||||||
|
|
||||||
hsAssert(fLocked == 0, "Don't currently support adding keys while locked");
|
hsAssert(fLocked == 0, "Don't currently support adding keys while locked");
|
||||||
if (fLocked == 0 && key != nil)
|
if (fLocked == 0 && key)
|
||||||
{
|
{
|
||||||
// If this is the first key added, we just became loaded
|
hsAssert(std::find(fKeys.begin(), fKeys.end(), key) == fKeys.end(), "Key already added");
|
||||||
if (fDynamicKeys.empty())
|
|
||||||
loadStatusChange = kDynLoaded;
|
|
||||||
|
|
||||||
hsAssert(fDynamicKeys.find(key) == fDynamicKeys.end(), "Key already added");
|
// first key to be added?
|
||||||
fDynamicKeys.insert(key);
|
if (fKeys.empty())
|
||||||
|
loadStatusChange = kTypeLoaded;
|
||||||
|
|
||||||
|
// Objects that already have an object ID will be respected.
|
||||||
|
// Totally new keys will not have one, but keys from other sources (patches) will.
|
||||||
|
if (key->GetUoid().GetObjectID() == 0)
|
||||||
|
{
|
||||||
|
fKeys.push_back(key);
|
||||||
|
key->SetObjectID(fKeys.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t id = key->GetUoid().GetObjectID();
|
||||||
|
if (fKeys.size() < id)
|
||||||
|
fKeys.resize(id);
|
||||||
|
fKeys[id - 1] = key;
|
||||||
|
}
|
||||||
|
++fReffedKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void plRegistryKeyList::SetKeyUsed(plKeyImp* key)
|
|
||||||
{
|
|
||||||
// If this is a static key, mark that we used it. Otherwise, just ignore it.
|
|
||||||
uint32_t id = key->GetUoid().GetObjectID();
|
|
||||||
if (id > 0)
|
|
||||||
fReffedStaticKeys++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange)
|
bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange)
|
||||||
{
|
{
|
||||||
loadStatusChange = kNoChange;
|
loadStatusChange = kNoChange;
|
||||||
@ -219,122 +163,50 @@ bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it's a static key
|
|
||||||
uint32_t id = key->GetUoid().GetObjectID();
|
uint32_t id = key->GetUoid().GetObjectID();
|
||||||
hsAssert(id <= fStaticKeys.size(), "Bad static key id");
|
hsAssert(id <= fKeys.size(), "Bad static key id");
|
||||||
if (id != 0 && id <= fStaticKeys.size())
|
|
||||||
|
// Fixed Keys will have id == 0. Let's just make sure we have it before we toss it.
|
||||||
|
if (id == 0)
|
||||||
{
|
{
|
||||||
fReffedStaticKeys--;
|
hsAssert(key->GetUoid().GetLocation() == plLocation::kGlobalFixedLoc, "key id == 0 but not fixed?");
|
||||||
if (fLocked == 0)
|
if (!FindKey(key->GetName()))
|
||||||
IRepack();
|
|
||||||
|
|
||||||
// That was our last used static key, we're static unloaded
|
|
||||||
if (fReffedStaticKeys == 0)
|
|
||||||
loadStatusChange = kStaticUnloaded;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to find it in the dynamic key list
|
|
||||||
DynSet::iterator dynIt = fDynamicKeys.find(key);
|
|
||||||
if (dynIt != fDynamicKeys.end())
|
|
||||||
{
|
|
||||||
hsAssert(fLocked == 0, "Don't currently support removing dynamic keys while locked");
|
|
||||||
if (fLocked == 0)
|
|
||||||
{
|
{
|
||||||
fDynamicKeys.erase(dynIt);
|
hsAssert(false, "Couldn't find fixed key!");
|
||||||
delete key;
|
return false;
|
||||||
|
|
||||||
// That was our last dynamic key, notify of dynamic unloaded
|
|
||||||
if (fDynamicKeys.empty())
|
|
||||||
loadStatusChange = kDynUnloaded;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (id > fKeys.size())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
hsAssert(0, "Couldn't find this key, what is it?");
|
// Got that key, decrement the key counter
|
||||||
return false;
|
--fReffedKeys;
|
||||||
}
|
if (fReffedKeys == 0)
|
||||||
|
loadStatusChange = kTypeUnloaded;
|
||||||
//// IRepack /////////////////////////////////////////////////////////////////
|
return true;
|
||||||
// Frees the memory for our static key array if none of them are loaded
|
|
||||||
void plRegistryKeyList::IRepack()
|
|
||||||
{
|
|
||||||
if (fReffedStaticKeys == 0 && !fStaticKeys.empty())
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < fStaticKeys.size(); i++)
|
|
||||||
delete fStaticKeys[i];
|
|
||||||
|
|
||||||
fStaticKeys.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void plRegistryKeyList::PrepForWrite()
|
|
||||||
{
|
|
||||||
// If we have any static keys already, we were read in. To keep from
|
|
||||||
// invalidating old key indexes any new keys have to go on the end, hence we're
|
|
||||||
// unsorted now.
|
|
||||||
if (!fStaticKeys.empty())
|
|
||||||
fFlags |= kStaticUnsorted;
|
|
||||||
|
|
||||||
// If a dynamic keys doesn't have an object assigned to it, we're not writing
|
|
||||||
// it out. Figure out how many valid keys we have.
|
|
||||||
int numDynKeys = 0;
|
|
||||||
DynSet::const_iterator cIt;
|
|
||||||
for (cIt = fDynamicKeys.begin(); cIt != fDynamicKeys.end(); cIt++)
|
|
||||||
{
|
|
||||||
plKeyImp* key = *cIt;
|
|
||||||
// We're only going to write out keys that have objects
|
|
||||||
if (key->ObjectIsLoaded())
|
|
||||||
numDynKeys++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start our new object id's after any already created ones
|
|
||||||
uint32_t objectID = fStaticKeys.size()+1;
|
|
||||||
// Make room for our new keys
|
|
||||||
fStaticKeys.resize(fStaticKeys.size()+numDynKeys);
|
|
||||||
|
|
||||||
DynSet::iterator it = fDynamicKeys.begin();
|
|
||||||
while (it != fDynamicKeys.end())
|
|
||||||
{
|
|
||||||
plKeyImp* key = *it;
|
|
||||||
it++;
|
|
||||||
|
|
||||||
// If we're gonna use this key, tag it with it's object id and move it to the static array.
|
|
||||||
if (key->ObjectIsLoaded())
|
|
||||||
{
|
|
||||||
key->SetObjectID(objectID);
|
|
||||||
fStaticKeys[objectID-1] = key;
|
|
||||||
|
|
||||||
objectID++;
|
|
||||||
fReffedStaticKeys++;
|
|
||||||
fDynamicKeys.erase(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void plRegistryKeyList::Read(hsStream* s)
|
void plRegistryKeyList::Read(hsStream* s)
|
||||||
{
|
{
|
||||||
uint32_t keyListLen = s->ReadLE32();
|
uint32_t keyListLen = s->ReadLE32();
|
||||||
if (!fStaticKeys.empty())
|
if (!fKeys.empty())
|
||||||
{
|
{
|
||||||
s->Skip(keyListLen);
|
s->Skip(keyListLen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fFlags = s->ReadByte();
|
// deprecated flags. used to indicate alphabetically sorted keys for some "optimization"
|
||||||
|
// that really appeared to do nothing. no loss.
|
||||||
|
s->ReadByte();
|
||||||
|
|
||||||
uint32_t numKeys = s->ReadLE32();
|
uint32_t numKeys = s->ReadLE32();
|
||||||
fStaticKeys.resize(numKeys);
|
fKeys.reserve(numKeys);
|
||||||
|
|
||||||
for (int 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);
|
||||||
fStaticKeys[i] = newKey;
|
fKeys.push_back(newKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,17 +215,13 @@ void plRegistryKeyList::Write(hsStream* s)
|
|||||||
// Save space for the length of our data
|
// Save space for the length of our data
|
||||||
uint32_t beginPos = s->GetPosition();
|
uint32_t beginPos = s->GetPosition();
|
||||||
s->WriteLE32(0);
|
s->WriteLE32(0);
|
||||||
s->WriteByte(fFlags);
|
s->WriteByte(0); // Deprecated flags
|
||||||
|
|
||||||
int numKeys = fStaticKeys.size();
|
s->WriteLE32(fKeys.size());
|
||||||
s->WriteLE32(numKeys);
|
|
||||||
|
|
||||||
// Write out all our keys (anything in dynamic is unused, so just ignore those)
|
// Write out all our keys
|
||||||
for (int i = 0; i < numKeys; i++)
|
for (auto it = fKeys.begin(); it != fKeys.end(); ++it)
|
||||||
{
|
(*it)->Write(s);
|
||||||
plKeyImp* key = fStaticKeys[i];
|
|
||||||
key->Write(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go back to the start and write the length of our data
|
// Go back to the start and write the length of our data
|
||||||
uint32_t endPos = s->GetPosition();
|
uint32_t endPos = s->GetPosition();
|
||||||
|
@ -42,22 +42,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#ifndef plRegistryKeyList_h_inc
|
#ifndef plRegistryKeyList_h_inc
|
||||||
#define plRegistryKeyList_h_inc
|
#define plRegistryKeyList_h_inc
|
||||||
|
|
||||||
#include "HeadSpin.h"
|
|
||||||
#include "pnKeyedObject/plKeyImp.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
|
class plKeyImp;
|
||||||
class plRegistryKeyIterator;
|
class plRegistryKeyIterator;
|
||||||
|
class hsStream;
|
||||||
class KeySorter
|
class plString;
|
||||||
{
|
class plUoid;
|
||||||
public:
|
|
||||||
bool operator() (plKeyImp* k1, plKeyImp* k2) const
|
|
||||||
{
|
|
||||||
hsAssert(k1 && k2, "Should have valid keys here");
|
|
||||||
return k1->GetName().Compare(k2->GetName(), plString::kCaseInsensitive) < 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// List of keys for a single class type.
|
// List of keys for a single class type.
|
||||||
@ -68,60 +59,41 @@ protected:
|
|||||||
friend class plKeyFinder;
|
friend class plKeyFinder;
|
||||||
|
|
||||||
uint16_t fClassType;
|
uint16_t fClassType;
|
||||||
// Lock counter for iterating. If this is >0, don't do any ops that
|
uint32_t fLocked;
|
||||||
// can change key positions in the array (instead, just leave holes)
|
uint32_t fReffedKeys;
|
||||||
uint16_t fLocked;
|
|
||||||
|
|
||||||
enum Flags { kStaticUnsorted = 0x1 };
|
std::vector<plKeyImp*> fKeys;
|
||||||
uint8_t fFlags;
|
|
||||||
|
|
||||||
// Static keys are one's we read off disk. These don't change and are
|
|
||||||
// assumed to be already sorted when they're read in.
|
|
||||||
typedef std::vector<plKeyImp*> StaticVec;
|
|
||||||
StaticVec fStaticKeys;
|
|
||||||
uint32_t fReffedStaticKeys; // Number of static keys that are loaded
|
|
||||||
|
|
||||||
// Dynamic keys are anything created at runtime. They are put in the
|
|
||||||
// correct sorted position when they are added
|
|
||||||
typedef std::set<plKeyImp*, KeySorter> DynSet;
|
|
||||||
DynSet fDynamicKeys;
|
|
||||||
|
|
||||||
plRegistryKeyList() {}
|
plRegistryKeyList() {}
|
||||||
|
|
||||||
void ILock();
|
|
||||||
void IUnlock();
|
|
||||||
|
|
||||||
void IRepack();
|
void IRepack();
|
||||||
|
void ILock() { ++fLocked; }
|
||||||
|
void IUnlock() { --fLocked; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
plRegistryKeyList(uint16_t classType);
|
enum LoadStatus
|
||||||
|
{
|
||||||
|
kNoChange,
|
||||||
|
kTypeLoaded,
|
||||||
|
kTypeUnloaded
|
||||||
|
};
|
||||||
|
|
||||||
|
plRegistryKeyList(uint16_t classType)
|
||||||
|
: fClassType(classType), fReffedKeys(0), fLocked(0)
|
||||||
|
{ }
|
||||||
~plRegistryKeyList();
|
~plRegistryKeyList();
|
||||||
|
|
||||||
uint16_t GetClassType() const { return fClassType; }
|
uint16_t GetClassType() const { return fClassType; }
|
||||||
|
|
||||||
// Find a key by name (case-insensitive)
|
plKeyImp* FindKey(const plString& keyName) const;
|
||||||
plKeyImp* FindKey(const plString& keyName);
|
plKeyImp* FindKey(const plUoid& uoid) const;
|
||||||
// Find a key by uoid index.
|
|
||||||
plKeyImp* FindKey(const plUoid& uoid);
|
|
||||||
|
|
||||||
bool IterateKeys(plRegistryKeyIterator* iterator);
|
bool IterateKeys(plRegistryKeyIterator* iterator);
|
||||||
|
|
||||||
// Changes in our load status that can be caused by loading or unloading a key
|
|
||||||
enum LoadStatus
|
|
||||||
{
|
|
||||||
kNoChange,
|
|
||||||
kDynLoaded,
|
|
||||||
kDynUnloaded,
|
|
||||||
kStaticUnloaded,
|
|
||||||
};
|
|
||||||
void AddKey(plKeyImp* key, LoadStatus& loadStatusChange);
|
void AddKey(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||||
void SetKeyUsed(plKeyImp* key);
|
void SetKeyUsed(plKeyImp* key) { ++fReffedKeys; }
|
||||||
bool SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange);
|
bool SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange);
|
||||||
|
|
||||||
// Export time only. Before we write to disk, assign all the static keys
|
|
||||||
// object ID's that they can use to do fast lookups at load time.
|
|
||||||
void PrepForWrite();
|
|
||||||
|
|
||||||
void Read(hsStream* s);
|
void Read(hsStream* s);
|
||||||
void Write(hsStream* s);
|
void Write(hsStream* s);
|
||||||
};
|
};
|
||||||
|
@ -55,8 +55,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
plRegistryPageNode::plRegistryPageNode(const plFileName& path)
|
plRegistryPageNode::plRegistryPageNode(const plFileName& path)
|
||||||
: fValid(kPageCorrupt)
|
: fValid(kPageCorrupt)
|
||||||
, fPath(path)
|
, fPath(path)
|
||||||
, fDynLoadedTypes(0)
|
, fLoadedTypes(0)
|
||||||
, fStaticLoadedTypes(0)
|
|
||||||
, fOpenRequests(0)
|
, fOpenRequests(0)
|
||||||
, fIsNewPage(false)
|
, fIsNewPage(false)
|
||||||
{
|
{
|
||||||
@ -73,8 +72,7 @@ plRegistryPageNode::plRegistryPageNode(const plLocation& location, const plStrin
|
|||||||
const plString& page, const plFileName& dataPath)
|
const plString& page, const plFileName& dataPath)
|
||||||
: fValid(kPageOk)
|
: fValid(kPageOk)
|
||||||
, fPageInfo(location)
|
, fPageInfo(location)
|
||||||
, fDynLoadedTypes(0)
|
, fLoadedTypes(0)
|
||||||
, fStaticLoadedTypes(0)
|
|
||||||
, fOpenRequests(0)
|
, fOpenRequests(0)
|
||||||
, fIsNewPage(true)
|
, fIsNewPage(true)
|
||||||
{
|
{
|
||||||
@ -182,7 +180,7 @@ void plRegistryPageNode::LoadKeys()
|
|||||||
|
|
||||||
stream->SetPosition(oldPos);
|
stream->SetPosition(oldPos);
|
||||||
CloseStream();
|
CloseStream();
|
||||||
fStaticLoadedTypes = fKeyLists.size();
|
fLoadedTypes = fKeyLists.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void plRegistryPageNode::UnloadKeys()
|
void plRegistryPageNode::UnloadKeys()
|
||||||
@ -195,8 +193,7 @@ void plRegistryPageNode::UnloadKeys()
|
|||||||
}
|
}
|
||||||
fKeyLists.clear();
|
fKeyLists.clear();
|
||||||
|
|
||||||
fDynLoadedTypes = 0;
|
fLoadedTypes = 0;
|
||||||
fStaticLoadedTypes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//// plWriteIterator /////////////////////////////////////////////////////////
|
//// plWriteIterator /////////////////////////////////////////////////////////
|
||||||
@ -235,8 +232,6 @@ void plRegistryPageNode::Write()
|
|||||||
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
for (it = fKeyLists.begin(); it != fKeyLists.end(); it++)
|
||||||
{
|
{
|
||||||
plRegistryKeyList* keyList = it->second;
|
plRegistryKeyList* keyList = it->second;
|
||||||
keyList->PrepForWrite();
|
|
||||||
|
|
||||||
int ver = plVersion::GetCreatableVersion(keyList->GetClassType());
|
int ver = plVersion::GetCreatableVersion(keyList->GetClassType());
|
||||||
fPageInfo.AddClassVersion(keyList->GetClassType(), ver);
|
fPageInfo.AddClassVersion(keyList->GetClassType(), ver);
|
||||||
}
|
}
|
||||||
@ -358,8 +353,8 @@ void plRegistryPageNode::AddKey(plKeyImp* key)
|
|||||||
plRegistryKeyList::LoadStatus loadStatusChange;
|
plRegistryKeyList::LoadStatus loadStatusChange;
|
||||||
keys->AddKey(key, loadStatusChange);
|
keys->AddKey(key, loadStatusChange);
|
||||||
|
|
||||||
if (loadStatusChange == plRegistryKeyList::kDynLoaded)
|
if (loadStatusChange == plRegistryKeyList::kTypeLoaded)
|
||||||
fDynLoadedTypes++;
|
++fLoadedTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plRegistryPageNode::SetKeyUsed(plKeyImp* key)
|
void plRegistryPageNode::SetKeyUsed(plKeyImp* key)
|
||||||
@ -381,10 +376,8 @@ bool plRegistryPageNode::SetKeyUnused(plKeyImp* key)
|
|||||||
bool removed = keys->SetKeyUnused(key, loadStatusChange);
|
bool removed = keys->SetKeyUnused(key, loadStatusChange);
|
||||||
|
|
||||||
// If the key type just changed load status, update our load counts
|
// If the key type just changed load status, update our load counts
|
||||||
if (loadStatusChange == plRegistryKeyList::kDynUnloaded)
|
if (loadStatusChange == plRegistryKeyList::kTypeUnloaded)
|
||||||
fDynLoadedTypes--;
|
--fLoadedTypes;
|
||||||
else if (loadStatusChange == plRegistryKeyList::kStaticUnloaded)
|
|
||||||
fStaticLoadedTypes--;
|
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,7 @@ protected:
|
|||||||
// Map from class type to a list of keys of that type
|
// Map from class type to a list of keys of that type
|
||||||
typedef std::map<uint16_t, plRegistryKeyList*> KeyMap;
|
typedef std::map<uint16_t, plRegistryKeyList*> KeyMap;
|
||||||
KeyMap fKeyLists;
|
KeyMap fKeyLists;
|
||||||
int fDynLoadedTypes; // The number of key types that have dynamic keys loaded
|
uint32_t fLoadedTypes; // The number of key types that have dynamic keys loaded
|
||||||
int fStaticLoadedTypes; // The number of key types that have all their keys loaded
|
|
||||||
|
|
||||||
PageCond fValid; // Condition of the page
|
PageCond fValid; // Condition of the page
|
||||||
plFileName fPath; // Path to the page file
|
plFileName fPath; // Path to the page file
|
||||||
@ -104,9 +103,9 @@ public:
|
|||||||
PageCond GetPageCondition() { return fValid; }
|
PageCond GetPageCondition() { return fValid; }
|
||||||
|
|
||||||
// True if we have any static or dynamic keys loaded
|
// True if we have any static or dynamic keys loaded
|
||||||
bool IsLoaded() const { return fDynLoadedTypes > 0 || fStaticLoadedTypes > 0; }
|
bool IsLoaded() const { return fLoadedTypes > 0; }
|
||||||
// True if all of our static keys are loaded
|
// True if all of our static keys are loaded
|
||||||
bool IsFullyLoaded() const { return (fStaticLoadedTypes == fKeyLists.size() && !fKeyLists.empty()) || fIsNewPage; }
|
bool IsFullyLoaded() const { return (fLoadedTypes == fKeyLists.size() && !fKeyLists.empty()) || fIsNewPage; }
|
||||||
|
|
||||||
// Export time only. If we want to reuse a page, load the keys we want then
|
// Export time only. If we want to reuse a page, load the keys we want then
|
||||||
// call SetNewPage, so it will be considered a new page from now on. That
|
// call SetNewPage, so it will be considered a new page from now on. That
|
||||||
|
Reference in New Issue
Block a user