Browse Source

Merge pull request #264 from Hoikas/keylist

Refactor RegistryKeyList
Branan Purvine-Riley 12 years ago
parent
commit
7041aef647
  1. 4
      Sources/Plasma/NucleusLib/pnKeyedObject/hsKeyedObject.cpp
  2. 14
      Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp
  3. 278
      Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp
  4. 72
      Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h
  5. 23
      Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp
  6. 7
      Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h

4
Sources/Plasma/NucleusLib/pnKeyedObject/hsKeyedObject.cpp

@ -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
{ {

14
Sources/Plasma/PubUtilLib/plResMgr/plKeyFinder.cpp

@ -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

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

@ -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,23 +125,30 @@ 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;
}
void plRegistryKeyList::SetKeyUsed(plKeyImp* key) // 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 this is a static key, mark that we used it. Otherwise, just ignore it. if (key->GetUoid().GetObjectID() == 0)
uint32_t id = key->GetUoid().GetObjectID(); {
if (id > 0) fKeys.push_back(key);
fReffedStaticKeys++; key->SetObjectID(fKeys.size());
}
else
{
uint32_t id = key->GetUoid().GetObjectID();
if (fKeys.size() < id)
fKeys.resize(id);
fKeys[id - 1] = key;
}
++fReffedKeys;
}
} }
bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange) bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange)
@ -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())
{
fReffedStaticKeys--;
if (fLocked == 0)
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 // Fixed Keys will have id == 0. Let's just make sure we have it before we toss it.
DynSet::iterator dynIt = fDynamicKeys.find(key); if (id == 0)
if (dynIt != fDynamicKeys.end())
{ {
hsAssert(fLocked == 0, "Don't currently support removing dynamic keys while locked"); hsAssert(key->GetUoid().GetLocation() == plLocation::kGlobalFixedLoc, "key id == 0 but not fixed?");
if (fLocked == 0) if (!FindKey(key->GetName()))
{ {
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;
} }
return false;
}
hsAssert(0, "Couldn't find this key, what is it?");
return false;
}
//// IRepack /////////////////////////////////////////////////////////////////
// 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++;
} }
else if (id > fKeys.size())
return false;
// Start our new object id's after any already created ones // Got that key, decrement the key counter
uint32_t objectID = fStaticKeys.size()+1; --fReffedKeys;
// Make room for our new keys if (fReffedKeys == 0)
fStaticKeys.resize(fStaticKeys.size()+numDynKeys); loadStatusChange = kTypeUnloaded;
return true;
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();

72
Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.h

@ -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);
}; };

23
Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.cpp

@ -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;
} }

7
Sources/Plasma/PubUtilLib/plResMgr/plRegistryNode.h

@ -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

Loading…
Cancel
Save