From 789c937635b6233a2c91dbb3937bb9d5cf98270c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Jan 2011 00:17:13 +0000 Subject: [PATCH] - use FSharedStringArena to handle AActor's tag strings properly. They were names before which are not case sensitive and could cause problems. - fixed FSharedStringArena::FreeAll did not NULL TopBlock. - bumped savegame version for above changes. SVN r3100 (trunk) --- src/actor.h | 5 ++++- src/memarena.cpp | 1 + src/memarena.h | 6 ++++++ src/p_acs.cpp | 2 +- src/p_mobj.cpp | 30 +++++++++++++++++++++++++--- src/thingdef/thingdef_properties.cpp | 2 +- src/version.h | 2 +- 7 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/actor.h b/src/actor.h index 13425e48a..53145b7c1 100644 --- a/src/actor.h +++ b/src/actor.h @@ -39,6 +39,7 @@ #include "textures/textures.h" #include "r_blend.h" #include "s_sound.h" +#include "memarena.h" struct subsector_t; // @@ -760,6 +761,7 @@ public: fixed_t GetGravity() const; bool IsSentient() const; const char *GetTag(const char *def = NULL) const; + void SetTag(const char *def); // info for drawing @@ -855,7 +857,7 @@ public: int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL int lastbump; // Last time the actor was bumped, used to control BUMPSPECIAL int Score; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything. - FNameNoInit Tag; // Strife's tag name. FIXME: should be case sensitive! + FString * Tag; // Strife's tag name. AActor *BlockingMobj; // Actor that blocked the last move line_t *BlockingLine; // Line that blocked the last move @@ -927,6 +929,7 @@ public: private: static AActor *TIDHash[128]; static inline int TIDHASH (int key) { return key & 127; } + static FSharedStringArena mStringPropertyData; friend class FActorIterator; diff --git a/src/memarena.cpp b/src/memarena.cpp index c44586dee..21cee59a6 100644 --- a/src/memarena.cpp +++ b/src/memarena.cpp @@ -373,4 +373,5 @@ void FSharedStringArena::FreeAll() FreeBlocks = block; } memset(Buckets, 0, sizeof(Buckets)); + TopBlock = NULL; } diff --git a/src/memarena.h b/src/memarena.h index e933fc072..823672018 100644 --- a/src/memarena.h +++ b/src/memarena.h @@ -31,6 +31,9 @@ ** */ +#ifndef __MEMARENA_H +#define __MEMARENA_H + #include "zstring.h" // A general purpose arena. @@ -81,3 +84,6 @@ protected: private: void *Alloc(size_t size) { return NULL; } // No access to FMemArena::Alloc for outsiders. }; + + +#endif \ No newline at end of file diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 63c3f0a6c..8b54ffce2 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2709,7 +2709,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) actor->Score = value; case APROP_NameTag: - actor->Tag = FBehavior::StaticLookupString(value); + actor->SetTag(FBehavior::StaticLookupString(value)); break; case APROP_DamageFactor: diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 39a17bf76..31302cbc8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -300,7 +300,6 @@ void AActor::Serialize (FArchive &arc) << pushfactor << Species << Score - << Tag << lastpush << lastbump << PainThreshold << DamageFactor @@ -309,6 +308,17 @@ void AActor::Serialize (FArchive &arc) << PoisonDamage << PoisonDuration << PoisonPeriod << ConversationRoot << Conversation; + { + FString tagstr; + if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag; + arc << tagstr; + if (arc.IsLoading()) + { + if (tagstr.Len() == 0) Tag = NULL; + else Tag = mStringPropertyData.Alloc(tagstr); + } + } + if (arc.IsLoading ()) { touching_sectorlist = NULL; @@ -5521,11 +5531,13 @@ bool AActor::IsSentient() const } +FSharedStringArena AActor::mStringPropertyData; + const char *AActor::GetTag(const char *def) const { - if (Tag != NAME_None) + if (Tag != NULL) { - const char *tag = Tag.GetChars(); + const char *tag = Tag->GetChars(); if (tag[0] == '$') { return GStrings(tag + 1); @@ -5545,6 +5557,18 @@ const char *AActor::GetTag(const char *def) const } } +void AActor::SetTag(const char *def) +{ + if (def == NULL || *def == 0) + { + Tag = NULL; + } + else + { + Tag = mStringPropertyData.Alloc(def); + } +} + void AActor::ClearCounters() { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index f7221c435..efff2b665 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -299,7 +299,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor) DEFINE_PROPERTY(tag, S, Actor) { PROP_STRING_PARM(str, 0); - defaults->Tag = str; + defaults->SetTag(str); } //========================================================================== diff --git a/src/version.h b/src/version.h index 5edcb7108..bb2e096ac 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 3085 +#define MINSAVEVER 3100 #if SVN_REVISION_NUMBER < MINSAVEVER // If we don't know the current revision write something very high to ensure that