Add a PropList set to C4GameObjects to keep track of all proplists

Also remove C4EnumPointer2. It was only used for C4Player object pointers,
which only need an offset, not a range.
stable-5.2
Günther Brammer 2009-04-18 02:46:19 +02:00
parent abe1bad6bd
commit cb1e6e6a5c
10 changed files with 93 additions and 84 deletions

View File

@ -53,7 +53,10 @@ class C4GameObjects : public C4NotifyingObjectList
C4Object *FindInternal(C4ID id); // find object in first sector
virtual C4Object *ObjectPointer(int32_t iNumber); // object pointer by number
long ObjectNumber(C4PropList *pObj); // object number by pointer
int32_t ObjectNumber(C4PropList *pObj); // object number by pointer
C4Object* SafeObjectPointer(int32_t iNumber);
C4Object* Denumerated(C4Object *pObj);
C4Object* Enumerated(C4Object *pObj);
C4ObjectList &ObjectsInt(); // return object list containing system objects
@ -80,6 +83,9 @@ class C4GameObjects : public C4NotifyingObjectList
bool ValidateOwners();
bool AssignInfo();
protected:
C4Set<C4PropList *> PropLists;
friend class C4PropList;
};
class C4AulFunc;

View File

@ -420,6 +420,9 @@ class C4Object: public C4PropList
// This function is used for:
// -Objects that are not to be saved in "SaveScenario"-mode
bool IsUserPlayerObject();// true for any object that belongs to any player (NO_OWNER) or a specified player
// overloaded from C4PropList
virtual C4Object * GetObject() { return this; }
};
#endif

View File

@ -116,22 +116,16 @@ class C4ObjectList
BOOL AssignPlrViewRange();
StdStrBuf GetNameList(C4DefList &rDefs, DWORD dwCategory=C4D_All);
BOOL IsClear() const;
BOOL ReadEnumerated(const char *szSource);
BOOL DenumerateRead();
BOOL Write(char *szTarget);
void CompileFunc(StdCompiler *pComp, bool fSaveRefs = true, bool fSkipPlayerObjects = false);
long ObjectNumber(C4PropList *pObj);
bool IsContained(C4Object *pObj);
int ClearPointers(C4Object *pObj);
int ObjectCount(C4ID id=C4ID_None, int32_t dwCategory=C4D_All) const;
int MassCount();
int ListIDCount(int32_t dwCategory);
C4Object* Denumerated(C4Object *pObj);
C4Object* Enumerated(C4Object *pObj);
virtual C4Object* ObjectPointer(int32_t iNumber);
C4Object* SafeObjectPointer(int32_t iNumber);
C4Object* GetObject(int Index=0);
C4Object* Find(C4ID id, int iOwner=ANY_OWNER, DWORD dwOCF=OCF_All);
C4Object* FindOther(C4ID id, int iOwner=ANY_OWNER);

View File

@ -25,6 +25,7 @@ class C4PropList {
virtual void SetName (const char *NewName = 0);
virtual C4Def * GetDef();
virtual C4Object * GetObject();
C4PropList * GetPrototype() { return prototype; }
bool GetProperty(C4String * k, C4Value & to);

View File

@ -25,9 +25,6 @@ class C4Object;
class C4String;
class C4ValueArray;
const long C4EnumPointer1 = 1000000000,
C4EnumPointer2 = 1001000000;
// C4Value type
enum C4V_Type
{

View File

@ -277,19 +277,44 @@ C4Object *C4GameObjects::FindInternal(C4ID id)
C4Object *C4GameObjects::ObjectPointer(int32_t iNumber)
{
// search own list
C4Object *pObj = C4ObjectList::ObjectPointer(iNumber);
if (pObj) return pObj;
// search deactivated
return InactiveObjects.ObjectPointer(iNumber);
C4PropList *pObj = PropLists.Get(iNumber);
if (pObj) return pObj->GetObject();
}
long C4GameObjects::ObjectNumber(C4PropList * pObj)
int32_t C4GameObjects::ObjectNumber(C4PropList *pObj)
{
// search own list
long iNum = C4ObjectList::ObjectNumber(pObj);
if (iNum) return iNum;
// search deactivated
return InactiveObjects.ObjectNumber(pObj);
if(!pObj) return 0;
C4PropList * const * p = PropLists.First();
while (p)
{
if(*p == pObj) return (*p)->Number;
p = PropLists.Next(p);
}
return 0;
}
C4Object *C4GameObjects::SafeObjectPointer(int32_t iNumber)
{
C4Object *pObj = ObjectPointer(iNumber);
if (pObj) if (!pObj->Status) return NULL;
return pObj;
}
const uint32_t C4EnumPointer1 = 1000000000;
C4Object* C4GameObjects::Enumerated(C4Object *pObj)
{
uint32_t iPtrNum;
// If object is enumerated, convert to enumerated pointer
if (iPtrNum = ObjectNumber(pObj))
return (C4Object*) (C4EnumPointer1 + iPtrNum);
// Oops!
return (C4Object*)-1;
}
C4Object* C4GameObjects::Denumerated(C4Object *pObj)
{
// convert to pointer
return ObjectPointer((uint32_t)(intptr_t) pObj - C4EnumPointer1);
}
C4ObjectList &C4GameObjects::ObjectsInt()

View File

@ -229,7 +229,6 @@ C4Object::~C4Object()
#if defined(_DEBUG)
// debug: mustn't be listed in any list now
assert(!Game.Objects.ObjectNumber(this));
assert(!Game.Objects.InactiveObjects.ObjectNumber(this));
Game.Objects.Sectors.AssertObjectNotInList(this);
#endif
}

View File

@ -457,16 +457,6 @@ void C4ObjectList::Enumerate()
cLnk->Obj->EnumeratePointers();
}
long C4ObjectList::ObjectNumber(C4PropList *pObj)
{
C4ObjectLink *cLnk;
if(!pObj) return 0;
for (cLnk=First; cLnk; cLnk=cLnk->Next)
if (cLnk->Obj==pObj)
return cLnk->Obj->Number;
return 0;
}
bool C4ObjectList::IsContained(C4Object *pObj)
{
C4ObjectLink *cLnk;
@ -481,12 +471,6 @@ BOOL C4ObjectList::IsClear() const
return (ObjectCount()==0);
}
BOOL C4ObjectList::ReadEnumerated(const char *szSource)
{
assert(false);
return FALSE;
}
BOOL C4ObjectList::DenumerateRead()
{
if(!pEnumerated) return FALSE;
@ -587,22 +571,6 @@ void C4ObjectList::CompileFunc(StdCompiler *pComp, bool fSaveRefs, bool fSkipPla
}
}
C4Object* C4ObjectList::ObjectPointer(int32_t iNumber)
{
C4ObjectLink *cLnk;
for (cLnk=First; cLnk; cLnk=cLnk->Next)
if (cLnk->Obj->Number==iNumber)
return cLnk->Obj;
return NULL;
}
C4Object *C4ObjectList::SafeObjectPointer(int32_t iNumber)
{
C4Object *pObj = ObjectPointer(iNumber);
if (pObj) if (!pObj->Status) return NULL;
return pObj;
}
StdStrBuf C4ObjectList::GetNameList(C4DefList &rDefs, DWORD dwCategory)
{
int cpos,idcount;
@ -658,25 +626,6 @@ void C4ObjectList::ClearInfo(C4ObjectInfo *pInfo)
cLnk->Obj->ClearInfo(pInfo);
}
C4Object* C4ObjectList::Enumerated(C4Object *pObj)
{
int iPtrNum;
// If object is enumerated, convert to enumerated pointer
if (iPtrNum = ObjectNumber(pObj))
return (C4Object*) (C4EnumPointer1 + iPtrNum);
// Oops!
return 0;
}
C4Object* C4ObjectList::Denumerated(C4Object *pObj)
{
// If valid enumeration, convert to pointer
if (Inside( (long) pObj, C4EnumPointer1, C4EnumPointer2 ))
return ObjectPointer( (long) pObj - C4EnumPointer1 );
// Oops!
return NULL;
}
void C4ObjectList::DrawList(C4Facet &cgo, int iSelection, DWORD dwCategory)
{
int iSections = cgo.GetSectionCount();

View File

@ -32,17 +32,20 @@ void C4PropList::AssignRemoval()
C4PropList::C4PropList():
FirstRef(NULL), prototype(0)
{
Game.Objects.PropLists.Add(this);
}
C4PropList::C4PropList(C4PropList * prototype):
FirstRef(NULL), prototype(prototype)
{
Game.Objects.PropLists.Add(this);
}
C4PropList::~C4PropList()
{
assert(!FirstRef);
while (FirstRef) FirstRef->Set(0);
Game.Objects.PropLists.Remove(this);
}
@ -67,6 +70,12 @@ void C4PropList::SetName(const char* NewName)
C4Object * C4PropList::GetObject()
{
if (prototype) return prototype->GetObject();
return 0;
}
C4Def * C4PropList::GetDef()
{
if (prototype) return prototype->GetDef();
@ -162,3 +171,34 @@ void C4PropList::ResetProperty(C4String * k)
{
Properties.Remove(k);
}
template<> template<>
unsigned int C4Set<C4PropList *>::Hash<int>(int e)
{
unsigned int hash = 4, tmp;
hash += e >> 16;
tmp = ((e & 0xffff) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
hash += hash >> 11;
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
template<> template<>
unsigned int C4Set<C4PropList *>::Hash<C4PropList *>(C4PropList * e)
{
return Hash(e->Number);
}
template<> template<>
bool C4Set<C4PropList *>::Equals<int>(C4PropList * a, int b)
{
return a->Number == b;
}

View File

@ -524,21 +524,20 @@ StdStrBuf C4Value::GetDataString()
return StdStrBuf(Data ? "true" : "false");
#ifdef C4ENGINE
case C4V_C4Object:
case C4V_PropList:
{
// obj exists?
if(!Game.Objects.ObjectNumber(Data.Obj) && !Game.Objects.InactiveObjects.ObjectNumber(Data.Obj))
if(!Game.Objects.ObjectNumber(Data.PropList))
return FormatString("%ld", Data.Int);
else
if (Data.Obj)
if (Data.PropList)
if (Data.Obj->Status == C4OS_NORMAL)
return FormatString("%s #%d", Data.Obj->GetName(), (int) Data.Obj->Number);
return FormatString("%s #%d", Data.PropList->GetName(), (int) Data.PropList->Number);
else
return FormatString("{%s #%d}", Data.Obj->GetName(), (int) Data.Obj->Number);
return FormatString("{%s #%d}", Data.PropList->GetName(), (int) Data.PropList->Number);
else
return StdStrBuf("0"); // (impossible)
}
case C4V_PropList:
return StdStrBuf("FIXME");
case C4V_String:
return (Data.Str && Data.Str->GetCStr()) ? FormatString("\"%s\"", Data.Str->GetCStr()) : StdStrBuf("(nullstring)");
case C4V_Array:
@ -592,13 +591,9 @@ void C4Value::DenumeratePointer()
}
// object types only
if(Type != C4V_C4ObjectEnum && Type != C4V_Any) return;
// in range?
if(Type != C4V_C4ObjectEnum && !Inside(Data.Int, C4EnumPointer1, C4EnumPointer2)) return;
// get obj id, search object
int iObjID = (Data.Int >= C4EnumPointer1 ? Data.Int - C4EnumPointer1 : Data.Int);
int iObjID = Data.Int;
C4PropList *pObj = Game.Objects.ObjectPointer(iObjID);
if (!pObj)
pObj = Game.Objects.InactiveObjects.ObjectPointer(iObjID);
if(pObj)
// set
SetPropList(pObj);