Rewritten MobTypesManager not to leak memory.
This commit is contained in:
parent
07a117b096
commit
359918127b
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 :
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user