Create preallocated C4Strings statically instead of allocating each one

This makes it easy to convert a C4String* to a C4PropertyName, which will
be useful for reflection of internal properties.
Günther Brammer 2010-12-06 16:24:41 +01:00
parent 26c670b29d
commit 4e4d32f86b
6 changed files with 81 additions and 72 deletions

View File

@ -1352,7 +1352,7 @@ C4PropList *C4Def::GetActionByName(C4String *actname)
{
assert(actname);
// If we get the null string or ActIdle by name, return NULL action
if (!actname || actname == Strings.P[P_Idle]) return NULL;
if (!actname || actname == &Strings.P[P_Idle]) return NULL;
// otherwise, query actmap
C4Value ActMap; GetProperty(P_ActMap, &ActMap);
if (!ActMap.getPropList()) return false;

View File

@ -1287,7 +1287,7 @@ bool C4Object::ChangeDef(C4ID idNew)
if (Contained) Exit(0,0,0,Fix0,Fix0,Fix0,false);
// Pre change resets
SetAction(0);
ResetProperty(::Strings.P[P_Action]); // Enforce ActIdle because SetAction may have failed due to NoOtherAction
ResetProperty(&Strings.P[P_Action]); // Enforce ActIdle because SetAction may have failed due to NoOtherAction
SetDir(0); // will drop any outdated flipdir
if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=NULL; }
Def->Count--;
@ -3468,7 +3468,7 @@ bool C4Object::SetActionByName(C4String *ActName,
{
assert(ActName);
// If we get the null string or ActIdle by name, set ActIdle
if (!ActName || ActName == Strings.P[P_Idle])
if (!ActName || ActName == &Strings.P[P_Idle])
return SetAction(0,0,0,iCalls,fForce);
C4Value ActMap; GetProperty(P_ActMap, &ActMap);
if (!ActMap.getPropList()) return false;
@ -4679,7 +4679,7 @@ void C4Object::ExecAction()
if (!next_action)
Action.Phase = 0;
// set new action if it's not Hold
else if (next_action == Strings.P[P_Hold])
else if (next_action == &Strings.P[P_Hold])
{
Action.Phase = pActionDef->GetPropertyInt(P_Length)-1;
Action.PhaseDelay = pActionDef->GetPropertyInt(P_Delay)-1;

View File

@ -228,7 +228,7 @@ const char * C4PropList::GetName()
void C4PropList::SetName(const char* NewName)
{
if (!NewName)
ResetProperty(Strings.P[P_Name]);
ResetProperty(&Strings.P[P_Name]);
else
{
SetProperty(P_Name, C4VString(NewName));
@ -296,7 +296,7 @@ bool C4PropList::GetPropertyByS(C4String * k, C4Value *pResult) const
C4String * C4PropList::GetPropertyStr(C4PropertyName n) const
{
C4String * k = Strings.P[n];
C4String * k = &Strings.P[n];
if (Properties.Has(k))
{
return Properties.Get(k).Value.getStr();
@ -310,7 +310,7 @@ C4String * C4PropList::GetPropertyStr(C4PropertyName n) const
int32_t C4PropList::GetPropertyInt(C4PropertyName n) const
{
C4String * k = Strings.P[n];
C4String * k = &Strings.P[n];
if (Properties.Has(k))
{
return Properties.Get(k).Value.getInt();
@ -325,8 +325,8 @@ int32_t C4PropList::GetPropertyInt(C4PropertyName n) const
void C4PropList::SetPropertyByS(C4String * k, const C4Value & to)
{
assert(!constant);
assert(Strings.Set.Has(k));
if (k == Strings.P[P_Prototype] && to.GetType() == C4V_PropList)
/*assert(Strings.Set.Has(k));*/
if (k == &Strings.P[P_Prototype] && to.GetType() == C4V_PropList)
{
prototype = to.GetData().PropList;
//return;

View File

@ -31,7 +31,7 @@ class C4Property
public:
C4Property() : Key(0) {}
C4Property(C4String *Key, const C4Value &Value) : Key(Key), Value(Value)
{ assert(Key); Key->IncRef(); assert(Strings.Set.Has(Key)); }
{ assert(Key); Key->IncRef(); /*assert(Strings.Set.Has(Key));*/ }
C4Property(const C4Property &o) : Key(o.Key), Value(o.Value) { if (Key) Key->IncRef(); }
C4Property & operator = (const C4Property &o)
{ assert(o.Key); o.Key->IncRef(); if (Key) Key->DecRef(); Key = o.Key; Value = o.Value; return *this; }
@ -65,13 +65,13 @@ public:
bool GetPropertyByS(C4String *k, C4Value *pResult) const;
bool GetProperty(C4PropertyName k, C4Value *pResult) const
{ return GetPropertyByS(Strings.P[k], pResult); }
{ return GetPropertyByS(&Strings.P[k], pResult); }
C4String * GetPropertyStr(C4PropertyName k) const;
int32_t GetPropertyInt(C4PropertyName k) const;
// not allowed on frozen proplists
void SetPropertyByS(C4String * k, const C4Value & to);
void SetProperty(C4PropertyName k, const C4Value & to)
{ SetPropertyByS(Strings.P[k], to); }
{ SetPropertyByS(&Strings.P[k], to); }
void ResetProperty(C4String * k);
static C4PropList * New(C4PropList * prototype = 0);

View File

@ -49,11 +49,16 @@ C4String::C4String(StdStrBuf strString)
{
// take string
Data.Take(std::move(strString));
Hash = C4Set<C4String*>::Hash(Data.getData());
Hash = Strings.Set.Hash(Data.getData());
// reg
Strings.Set.Add(this);
}
C4String::C4String()
: iRefCnt(0)
{
}
C4String::~C4String()
{
// unreg
@ -61,6 +66,17 @@ C4String::~C4String()
Strings.Set.Remove(this);
}
void C4String::operator=(const char * s)
{
assert(!iRefCnt);
assert(!Data);
// ref string
Data.Ref(s);
Hash = Strings.Set.Hash(Data.getData());
// reg
Strings.Set.Add(this);
}
void C4String::IncRef()
{
++iRefCnt;
@ -77,57 +93,57 @@ void C4String::DecRef()
C4StringTable::C4StringTable()
{
P[P_Prototype] = RegString("Prototype");
P[P_Name] = RegString("Name");
P[P_Collectible] = RegString("Collectible");
P[P_ActMap] = RegString("ActMap");
P[P_Procedure] = RegString("Procedure");
P[P_Attach] = RegString("Attach");
P[P_Directions] = RegString("Directions");
P[P_FlipDir] = RegString("FlipDir");
P[P_Length] = RegString("Length");
P[P_Delay] = RegString("Delay");
P[P_X] = RegString("X");
P[P_Y] = RegString("Y");
P[P_Wdt] = RegString("Wdt");
P[P_Hgt] = RegString("Hgt");
P[P_OffX] = RegString("OffX");
P[P_OffY] = RegString("OffY");
P[P_FacetBase] = RegString("FacetBase");
P[P_FacetTopFace] = RegString("FacetTopFace");
P[P_FacetTargetStretch] = RegString("FacetTargetStretch");
P[P_NextAction] = RegString("NextAction");
P[P_Hold] = RegString("Hold");
P[P_Idle] = RegString("Idle");
P[P_NoOtherAction] = RegString("NoOtherAction");
P[P_StartCall] = RegString("StartCall");
P[P_EndCall] = RegString("EndCall");
P[P_AbortCall] = RegString("AbortCall");
P[P_PhaseCall] = RegString("PhaseCall");
P[P_Sound] = RegString("Sound");
P[P_ObjectDisabled] = RegString("ObjectDisabled");
P[P_DigFree] = RegString("DigFree");
P[P_EnergyUsage] = RegString("EnergyUsage");
P[P_InLiquidAction] = RegString("InLiquidAction");
P[P_TurnAction] = RegString("TurnAction");
P[P_Reverse] = RegString("Reverse");
P[P_Step] = RegString("Step");
P[P_Animation] = RegString("Animation");
P[P_Action] = RegString("Action");
P[P_Visibility] = RegString("Visibility");
P[P_Parallaxity] = RegString("Parallaxity");
P[P_LineColors] = RegString("LineColors");
P[P_LineAttach] = RegString("LineAttach");
P[P_MouseDragImage] = RegString("MouseDragImage");
P[P_PictureTransformation] = RegString("PictureTransformation");
P[P_MeshTransformation] = RegString("MeshTransformation");
for (unsigned int i = 0; i < P_LAST; ++i) P[i]->IncRef();
P[P_Prototype] = "Prototype";
P[P_Name] = "Name";
P[P_Collectible] = "Collectible";
P[P_ActMap] = "ActMap";
P[P_Procedure] = "Procedure";
P[P_Attach] = "Attach";
P[P_Directions] = "Directions";
P[P_FlipDir] = "FlipDir";
P[P_Length] = "Length";
P[P_Delay] = "Delay";
P[P_X] = "X";
P[P_Y] = "Y";
P[P_Wdt] = "Wdt";
P[P_Hgt] = "Hgt";
P[P_OffX] = "OffX";
P[P_OffY] = "OffY";
P[P_FacetBase] = "FacetBase";
P[P_FacetTopFace] = "FacetTopFace";
P[P_FacetTargetStretch] = "FacetTargetStretch";
P[P_NextAction] = "NextAction";
P[P_Hold] = "Hold";
P[P_Idle] = "Idle";
P[P_NoOtherAction] = "NoOtherAction";
P[P_StartCall] = "StartCall";
P[P_EndCall] = "EndCall";
P[P_AbortCall] = "AbortCall";
P[P_PhaseCall] = "PhaseCall";
P[P_Sound] = "Sound";
P[P_ObjectDisabled] = "ObjectDisabled";
P[P_DigFree] = "DigFree";
P[P_EnergyUsage] = "EnergyUsage";
P[P_InLiquidAction] = "InLiquidAction";
P[P_TurnAction] = "TurnAction";
P[P_Reverse] = "Reverse";
P[P_Step] = "Step";
P[P_Animation] = "Animation";
P[P_Action] = "Action";
P[P_Visibility] = "Visibility";
P[P_Parallaxity] = "Parallaxity";
P[P_LineColors] = "LineColors";
P[P_LineAttach] = "LineAttach";
P[P_MouseDragImage] = "MouseDragImage";
P[P_PictureTransformation] = "PictureTransformation";
P[P_MeshTransformation] = "MeshTransformation";
// Prevent the individual strings from being deleted, they are not created with new
for (unsigned int i = 0; i < P_LAST; ++i) P[i].IncRef();
}
C4StringTable::~C4StringTable()
{
for (unsigned int i = 0; i < P_LAST; ++i) P[i]->DecRef();
assert(!Set.GetSize());
assert(Set.GetSize() == P_LAST);
}
C4String *C4StringTable::RegString(StdStrBuf String)
@ -144,12 +160,4 @@ C4String *C4StringTable::FindString(const char *strString)
return Set.Get(strString);
}
C4String *C4StringTable::FindString(C4String *pString)
{
for (C4String * const * i = Set.First(); i; i = Set.Next(i))
if (*i == pString)
return pString;
return NULL;
}
C4StringTable Strings;

View File

@ -30,7 +30,8 @@ class C4Group;
class C4String
{
explicit C4String(StdStrBuf strString);
explicit C4String(const char *strString);
C4String();
void operator=(const char * s);
StdCopyStrBuf Data; // string data
int iRefCnt; // reference count on string (by C4Value)
@ -227,11 +228,11 @@ public:
C4String *RegString(const char * s) { return RegString(StdStrBuf(s)); }
// Find existing C4String
C4String *FindString(const char *strString);
// Check wether the pointer is a C4String
C4String *FindString(C4String *pString);
C4String P[P_LAST];
private:
C4Set<C4String *> Set;
C4String * P[P_LAST];
friend class C4String;
};
extern C4StringTable Strings;