1
0

Rewritten MobTypesManager not to leak memory.

This commit is contained in:
madmaxoft 2013-10-20 13:10:21 +02:00
parent 07a117b096
commit 359918127b
2 changed files with 112 additions and 126 deletions

View File

@ -11,106 +11,41 @@
cMobTypesManager::tMobTypes2Names & cMobTypesManager::m_MobsTypes2Names(void) /** Map for cMonster::eType <-> string
Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
The strings need to be lowercase (for more efficient comparisons in StringToMobType())
*/
static const struct
{ {
// TODO: This memory leaks cMonster::eType m_Type;
static std::map<cMonster::eType, AString> * value = new std::map<cMonster::eType, AString>(MobTypes2NamesInitializerBeforeCx11()); const char * m_lcName;
return *value; } g_MobTypeNames[] =
}
cMobTypesManager::tMobTypes2Names cMobTypesManager::MobTypes2NamesInitializerBeforeCx11()
{
std::map<cMonster::eType, AString> toReturn;
typedef std::map<cMonster::eType, AString>::value_type ValueType;
// The strings need to be lowercase (for more efficient comparisons in StringToMobType())
toReturn.insert(ValueType(cMonster::mtBat, "bat"));
toReturn.insert(ValueType(cMonster::mtBlaze, "blaze"));
toReturn.insert(ValueType(cMonster::mtCaveSpider, "cavespider"));
toReturn.insert(ValueType(cMonster::mtChicken, "chicken"));
toReturn.insert(ValueType(cMonster::mtCow, "cow"));
toReturn.insert(ValueType(cMonster::mtCreeper, "creeper"));
toReturn.insert(ValueType(cMonster::mtEnderman, "enderman"));
toReturn.insert(ValueType(cMonster::mtGhast, "ghast"));
toReturn.insert(ValueType(cMonster::mtHorse, "horse"));
toReturn.insert(ValueType(cMonster::mtMagmaCube, "magmacube"));
toReturn.insert(ValueType(cMonster::mtMooshroom, "mooshroom"));
toReturn.insert(ValueType(cMonster::mtOcelot, "ocelot"));
toReturn.insert(ValueType(cMonster::mtPig, "pig"));
toReturn.insert(ValueType(cMonster::mtSheep, "sheep"));
toReturn.insert(ValueType(cMonster::mtSilverfish, "silverfish"));
toReturn.insert(ValueType(cMonster::mtSkeleton, "skeleton"));
toReturn.insert(ValueType(cMonster::mtSlime, "slime"));
toReturn.insert(ValueType(cMonster::mtSpider, "spider"));
toReturn.insert(ValueType(cMonster::mtSquid, "squid"));
toReturn.insert(ValueType(cMonster::mtVillager, "villager"));
toReturn.insert(ValueType(cMonster::mtWitch, "witch"));
toReturn.insert(ValueType(cMonster::mtWolf, "wolf"));
toReturn.insert(ValueType(cMonster::mtZombie, "zombie"));
toReturn.insert(ValueType(cMonster::mtZombiePigman, "zombiepigman"));
return toReturn;
}
cMobTypesManager::tMobType2Family & cMobTypesManager::m_MobsType2Family(void)
{ {
// TODO: This memory is leaked: {cMonster::mtBat, "bat"},
static std::map<cMonster::eType,cMonster::eFamily> * value = new std::map<cMonster::eType,cMonster::eFamily>(MobType2FamilyInitializerBeforeCx11()); {cMonster::mtBlaze, "blaze"},
return *value; {cMonster::mtCaveSpider, "cavespider"},
} {cMonster::mtChicken, "chicken"},
{cMonster::mtCow, "cow"},
{cMonster::mtCreeper, "creeper"},
{cMonster::mtEnderman, "enderman"},
{cMonster::mtGhast, "ghast"},
{cMonster::mtHorse, "horse"},
cMobTypesManager::tMobType2Family cMobTypesManager::MobType2FamilyInitializerBeforeCx11() {cMonster::mtMagmaCube, "magmacube"},
{ {cMonster::mtMooshroom, "mooshroom"},
std::map<cMonster::eType,cMonster::eFamily> toReturn; {cMonster::mtOcelot, "ocelot"},
typedef std::map<cMonster::eType,cMonster::eFamily>::value_type ValueType; {cMonster::mtPig, "pig"},
toReturn.insert(ValueType(cMonster::mtBat, cMonster::mfAmbient)); {cMonster::mtSheep, "sheep"},
toReturn.insert(ValueType(cMonster::mtBlaze, cMonster::mfHostile)); {cMonster::mtSilverfish, "silverfish"},
toReturn.insert(ValueType(cMonster::mtCaveSpider, cMonster::mfHostile)); {cMonster::mtSkeleton, "skeleton"},
toReturn.insert(ValueType(cMonster::mtChicken, cMonster::mfPassive)); {cMonster::mtSlime, "slime"},
toReturn.insert(ValueType(cMonster::mtCow, cMonster::mfPassive)); {cMonster::mtSpider, "spider"},
toReturn.insert(ValueType(cMonster::mtCreeper, cMonster::mfHostile)); {cMonster::mtSquid, "squid"},
toReturn.insert(ValueType(cMonster::mtEnderman, cMonster::mfHostile)); {cMonster::mtVillager, "villager"},
toReturn.insert(ValueType(cMonster::mtGhast, cMonster::mfHostile)); {cMonster::mtWitch, "witch"},
toReturn.insert(ValueType(cMonster::mtHorse, cMonster::mfPassive)); {cMonster::mtWolf, "wolf"},
toReturn.insert(ValueType(cMonster::mtMagmaCube, cMonster::mfHostile)); {cMonster::mtZombie, "zombie"},
toReturn.insert(ValueType(cMonster::mtMooshroom, cMonster::mfHostile)); {cMonster::mtZombiePigman, "zombiepigman"},
toReturn.insert(ValueType(cMonster::mtOcelot, cMonster::mfHostile)); } ;
toReturn.insert(ValueType(cMonster::mtPig, cMonster::mfPassive));
toReturn.insert(ValueType(cMonster::mtSheep, cMonster::mfPassive));
toReturn.insert(ValueType(cMonster::mtSilverfish, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtSkeleton, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtSlime, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtSpider, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtSquid, cMonster::mfWater));
toReturn.insert(ValueType(cMonster::mtVillager, cMonster::mfPassive));
toReturn.insert(ValueType(cMonster::mtWitch, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtWolf, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtZombie, cMonster::mfHostile));
toReturn.insert(ValueType(cMonster::mtZombiePigman, cMonster::mfHostile));
return toReturn;
}
cFastRandom & cMobTypesManager::m_Random(void)
{
// TODO: This memory is leaked:
static cFastRandom * value = new cFastRandom();
return *value;
}
@ -118,6 +53,8 @@ cFastRandom & cMobTypesManager::m_Random(void)
cMonster * cMobTypesManager::NewMonsterFromType(cMonster::eType a_MobType, int a_Size) cMonster * cMobTypesManager::NewMonsterFromType(cMonster::eType a_MobType, int a_Size)
{ {
cFastRandom Random;
cMonster * toReturn = NULL; cMonster * toReturn = NULL;
// unspecified size get rand[1,3] for Monsters that need size // unspecified size get rand[1,3] for Monsters that need size
@ -128,7 +65,7 @@ cMonster * cMobTypesManager::NewMonsterFromType(cMonster::eType a_MobType, int a
{ {
if (a_Size == -1) if (a_Size == -1)
{ {
a_Size = m_Random().NextInt(2, a_MobType) + 1; a_Size = Random.NextInt(2, a_MobType) + 1;
} }
if ((a_Size <= 0) || (a_Size >= 4)) if ((a_Size <= 0) || (a_Size >= 4))
{ {
@ -184,11 +121,16 @@ cMonster * cMobTypesManager::NewMonsterFromType(cMonster::eType a_MobType, int a
AString cMobTypesManager::MobTypeToString(cMonster::eType a_MobType) AString cMobTypesManager::MobTypeToString(cMonster::eType a_MobType)
{ {
std::map<cMonster::eType, AString>::const_iterator itr = m_MobsTypes2Names().find(a_MobType); // Mob types aren't sorted, so we need to search linearly:
if (itr != m_MobsTypes2Names().end()) for (int i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
{ {
return itr->second; if (g_MobTypeNames[i].m_Type == a_MobType)
{
return g_MobTypeNames[i].m_lcName;
}
} }
// Not found:
return ""; return "";
} }
@ -200,13 +142,37 @@ cMonster::eType cMobTypesManager::StringToMobType(const AString & a_Name)
{ {
AString lcName(a_Name); AString lcName(a_Name);
StrToLower(lcName); StrToLower(lcName);
for (std::map<cMonster::eType, AString>::const_iterator itr = m_MobsTypes2Names().begin(); itr != m_MobsTypes2Names().end(); itr++)
// Binary-search for the lowercase name:
int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames);
while (hi - lo > 1)
{ {
if (itr->second == a_Name) int mid = (lo + hi) / 2;
int res = strcmp(g_MobTypeNames[mid].m_lcName, lcName.c_str());
if (res == 0)
{ {
return itr->first; return g_MobTypeNames[mid].m_Type;
}
if (res < 0)
{
hi = mid;
}
else
{
lo = mid;
} }
} }
// Range has collapsed to at most two elements, compare each:
if (strcmp(g_MobTypeNames[lo].m_lcName, lcName.c_str()) == 0)
{
return g_MobTypeNames[lo].m_Type;
}
if ((lo != hi) && (strcmp(g_MobTypeNames[hi].m_lcName, lcName.c_str()) == 0))
{
return g_MobTypeNames[hi].m_Type;
}
// Not found:
return cMonster::mtInvalidType; return cMonster::mtInvalidType;
} }
@ -216,13 +182,46 @@ cMonster::eType cMobTypesManager::StringToMobType(const AString & a_Name)
cMonster::eFamily cMobTypesManager::FamilyFromType(cMonster::eType a_Type) cMonster::eFamily cMobTypesManager::FamilyFromType(cMonster::eType a_Type)
{ {
cMonster::eFamily toReturn = cMonster::mfMaxplusone; static const struct
std::map<cMonster::eType, cMonster::eFamily>::const_iterator itr = m_MobsType2Family().find(a_Type);
if (itr != m_MobsType2Family().end())
{ {
toReturn = itr->second; cMonster::eType m_Type;
cMonster::eFamily m_Family;
} TypeMap[] =
{
{cMonster::mtBat, cMonster::mfAmbient},
{cMonster::mtBlaze, cMonster::mfHostile},
{cMonster::mtCaveSpider, cMonster::mfHostile},
{cMonster::mtChicken, cMonster::mfPassive},
{cMonster::mtCow, cMonster::mfPassive},
{cMonster::mtCreeper, cMonster::mfHostile},
{cMonster::mtEnderman, cMonster::mfHostile},
{cMonster::mtGhast, cMonster::mfHostile},
{cMonster::mtHorse, cMonster::mfPassive},
{cMonster::mtMagmaCube, cMonster::mfHostile},
{cMonster::mtMooshroom, cMonster::mfHostile},
{cMonster::mtOcelot, cMonster::mfHostile},
{cMonster::mtPig, cMonster::mfPassive},
{cMonster::mtSheep, cMonster::mfPassive},
{cMonster::mtSilverfish, cMonster::mfHostile},
{cMonster::mtSkeleton, cMonster::mfHostile},
{cMonster::mtSlime, cMonster::mfHostile},
{cMonster::mtSpider, cMonster::mfHostile},
{cMonster::mtSquid, cMonster::mfWater},
{cMonster::mtVillager, cMonster::mfPassive},
{cMonster::mtWitch, cMonster::mfHostile},
{cMonster::mtWolf, cMonster::mfHostile},
{cMonster::mtZombie, cMonster::mfHostile},
{cMonster::mtZombiePigman, cMonster::mfHostile},
} ;
for (int i = 0; i < ARRAYCOUNT(TypeMap); i++)
{
if (TypeMap[i].m_Type == a_Type)
{
return TypeMap[i].m_Family;
}
} }
return toReturn; return cMonster::mfMaxplusone;
} }

View File

@ -15,9 +15,9 @@ class cFastRandom;
/** /**
This class aggregates static functions about mob types: This class aggregates static functions about mob types:
- create a mob from its type (as enum) (in that way it is a compiler-proxy for mobs) - create a mob from its type (as enum) (in that way it is a compiler-proxy for mobs)
- transform MobTypes from enums to string and vice versa - transform MobTypes from enums to string and vice versa
- return mob family from given type - return mob family from given type
*/ */
class cMobTypesManager class cMobTypesManager
{ {
@ -34,19 +34,6 @@ public:
asserts if invalid size for mobs that need size asserts if invalid size for mobs that need size
*/ */
static cMonster * NewMonsterFromType(cMonster::eType a_MobType, int a_Size = -1); static cMonster * NewMonsterFromType(cMonster::eType a_MobType, int a_Size = -1);
protected :
typedef const std::map<cMonster::eType,std::string> tMobTypes2Names;
static tMobTypes2Names& m_MobsTypes2Names(void);
static tMobTypes2Names MobTypes2NamesInitializerBeforeCx11(void);
typedef const std::map<cMonster::eType,cMonster::eFamily> tMobType2Family;
static tMobType2Family& m_MobsType2Family(void);
static tMobType2Family MobType2FamilyInitializerBeforeCx11(void);
static cFastRandom & m_Random(void);
public :
} ; } ;