From 6075f7cecd7c1a1f283c98eb0feeb746402a7c00 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 20 Oct 2013 14:00:45 +0200 Subject: [PATCH] Fixed memory leaks in cMobCensus, moved GetSpawnRate() to cMonster. --- source/Bindings.cpp | 33 +++++++++++++++++- source/Bindings.h | 2 +- source/MobCensus.cpp | 76 +++++++++++------------------------------ source/MobCensus.h | 15 +++----- source/Mobs/Monster.cpp | 17 +++++++++ source/Mobs/Monster.h | 3 ++ source/World.cpp | 41 +++++++++++----------- 7 files changed, 97 insertions(+), 90 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index e0ab2b2b3..f12894298 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 10/20/13 13:24:03. +** Generated automatically by tolua++-1.0.92 on 10/20/13 13:59:04. */ #ifndef __cplusplus @@ -29352,6 +29352,36 @@ static int tolua_AllToLua_cMonster_FamilyFromType00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetSpawnRate of class cMonster */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cMonster_GetSpawnRate00 +static int tolua_AllToLua_cMonster_GetSpawnRate00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cMonster",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cMonster::eFamily a_MobFamily = ((cMonster::eFamily) (int) tolua_tonumber(tolua_S,2,0)); + { + int tolua_ret = (int) cMonster::GetSpawnRate(a_MobFamily); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSpawnRate'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* Open function */ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) { @@ -31447,6 +31477,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"MobTypeToString",tolua_AllToLua_cMonster_MobTypeToString00); tolua_function(tolua_S,"StringToMobType",tolua_AllToLua_cMonster_StringToMobType00); tolua_function(tolua_S,"FamilyFromType",tolua_AllToLua_cMonster_FamilyFromType00); + tolua_function(tolua_S,"GetSpawnRate",tolua_AllToLua_cMonster_GetSpawnRate00); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cLineBlockTracer","cLineBlockTracer","",NULL); tolua_beginmodule(tolua_S,"cLineBlockTracer"); diff --git a/source/Bindings.h b/source/Bindings.h index cf3da377e..1917ff10c 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 10/20/13 13:24:04. +** Generated automatically by tolua++-1.0.92 on 10/20/13 13:59:05. */ /* Exported function */ diff --git a/source/MobCensus.cpp b/source/MobCensus.cpp index 67b154404..66b5932bc 100644 --- a/source/MobCensus.cpp +++ b/source/MobCensus.cpp @@ -7,59 +7,9 @@ -cMobCensus::tCapMultipliersMap cMobCensus::CapMultiplierInitializerBeforeCx11(void) -{ - std::map toReturn; - toReturn[cMonster::mfHostile] = 79; - toReturn[cMonster::mfPassive] = 11; - toReturn[cMonster::mfAmbient] = 16; - toReturn[cMonster::mfWater] = 5; - return toReturn; -} - - - - - -cMobCensus::tMobSpawnRate cMobCensus::MobSpawnRateInitializerBeforeCx11(void) -{ - std::map toReturn; - toReturn[cMonster::mfHostile] = 1; - toReturn[cMonster::mfPassive] = 400; - toReturn[cMonster::mfAmbient] = 400; - toReturn[cMonster::mfWater] = 400; - return toReturn; -} - - - - - -cMobCensus::tCapMultipliersMap & cMobCensus::m_CapMultipliers(void) -{ - // TODO: This memory leaks: - static tCapMultipliersMap * value = new tCapMultipliersMap(CapMultiplierInitializerBeforeCx11()); - return *value; -} - - - - - -cMobCensus::tMobSpawnRate & cMobCensus::m_SpawnRate(void) -{ - // TODO: This memory leaks: - static tMobSpawnRate* value = new tMobSpawnRate(MobSpawnRateInitializerBeforeCx11()); - return *value; -} - - - - - void cMobCensus::CollectMob(cMonster & a_Monster, cChunk & a_Chunk, double a_Distance) { - m_ProximityCounter.CollectMob(a_Monster,a_Chunk,a_Distance); + m_ProximityCounter.CollectMob(a_Monster, a_Chunk, a_Distance); m_MobFamilyCollecter.CollectMob(a_Monster); } @@ -73,11 +23,7 @@ bool cMobCensus::IsCapped(cMonster::eFamily a_MobFamily) const int ratio = 319; // this should be 256 as we are only supposed to take account from chunks that are in 17x17 from a player // but for now, we use all chunks loaded by players. that means 19 x 19 chunks. That's why we use 256 * (19*19) / (17*17) = 319 // MG TODO : code the correct count - tCapMultipliersMap::const_iterator capMultiplier = m_CapMultipliers().find(a_MobFamily); - if ( - (capMultiplier != m_CapMultipliers().end()) && - ((capMultiplier->second * GetNumChunks()) / ratio >= m_MobFamilyCollecter.GetNumberOfCollectedMobs(a_MobFamily)) - ) + if ((GetCapMultiplier(a_MobFamily) * GetNumChunks()) / ratio >= m_MobFamilyCollecter.GetNumberOfCollectedMobs(a_MobFamily)) { return false; } @@ -88,6 +34,23 @@ bool cMobCensus::IsCapped(cMonster::eFamily a_MobFamily) +int cMobCensus::GetCapMultiplier(cMonster::eFamily a_MobFamily) +{ + switch (a_MobFamily) + { + case cMonster::mfHostile: return 79; + case cMonster::mfPassive: return 11; + case cMonster::mfAmbient: return 16; + case cMonster::mfWater: return 5; + } + ASSERT(!"Unhandled mob family"); + return -1; +} + + + + + void cMobCensus::CollectSpawnableChunk(cChunk & a_Chunk) { m_EligibleForSpawnChunks.insert(&a_Chunk); @@ -126,3 +89,4 @@ void cMobCensus::Logd() + diff --git a/source/MobCensus.h b/source/MobCensus.h index 7606efcea..e3892bec6 100644 --- a/source/MobCensus.h +++ b/source/MobCensus.h @@ -25,9 +25,6 @@ as side effect 2 : it also know the caps for mobs number and can compare census class cMobCensus { public: - typedef const std::map tMobSpawnRate; - static tMobSpawnRate & m_SpawnRate(void); - /// Returns the nested proximity counter cMobProximityCounter & GetProximityCounter(void); @@ -40,25 +37,21 @@ public: /// Returns true if the family is capped (i.e. there are more mobs of this family than max) bool IsCapped(cMonster::eFamily a_MobFamily); - + /// log the results of census to server console void Logd(void); - + protected : cMobProximityCounter m_ProximityCounter; cMobFamilyCollecter m_MobFamilyCollecter; - typedef const std::map tCapMultipliersMap; - - static tCapMultipliersMap & m_CapMultipliers(void); - std::set m_EligibleForSpawnChunks; /// Returns the number of chunks that are elligible for spawning (for now, the loaded, valid chunks) int GetNumChunks(); - static tCapMultipliersMap CapMultiplierInitializerBeforeCx11(void); - static tCapMultipliersMap MobSpawnRateInitializerBeforeCx11(void); + /// Returns the cap multiplier value of the given monster family + static int GetCapMultiplier(cMonster::eFamily a_MobFamily); } ; diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index ffc42cb07..c5b116db4 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -616,6 +616,23 @@ cMonster::eFamily cMonster::FamilyFromType(eType a_Type) +int cMonster::GetSpawnRate(cMonster::eFamily a_MobFamily) +{ + switch (a_MobFamily) + { + case mfHostile: return 1; + case mfPassive: return 400; + case mfAmbient: return 400; + case mfWater: return 400; + } + ASSERT(!"Unhandled mob family"); + return -1; +} + + + + + cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType, int a_Size) { cFastRandom Random; diff --git a/source/Mobs/Monster.h b/source/Mobs/Monster.h index 3b7f40c00..14c72ed73 100644 --- a/source/Mobs/Monster.h +++ b/source/Mobs/Monster.h @@ -146,6 +146,9 @@ public: /// Returns the mob family based on the type static eFamily FamilyFromType(eType a_MobType); + /// Returns the spawn rate (number of game ticks between spawn attempts) for the given mob family + static int GetSpawnRate(cMonster::eFamily a_MobFamily); + // tolua_end /** Creates a new object of the specified mob. diff --git a/source/World.cpp b/source/World.cpp index 901337879..dad36ead4 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -744,32 +744,31 @@ void cWorld::TickMobs(float a_Dt) // before every Mob action, we have to "counts" them depending on the distance to players, on their megatype ... cMobCensus MobCensus; m_ChunkMap->CollectMobCensus(MobCensus); - for(cMobFamilyCollecter::tMobFamilyList::const_iterator itr = cMobFamilyCollecter::m_AllFamilies().begin(); itr != cMobFamilyCollecter::m_AllFamilies().end(); itr++) + if (m_bAnimals) { - cMobCensus::tMobSpawnRate::const_iterator spawnrate = cMobCensus::m_SpawnRate().find(*itr); - // hostile mobs are spawned more often - if ((spawnrate != cMobCensus::m_SpawnRate().end()) && (m_LastSpawnMonster[*itr] < m_WorldAge - spawnrate->second)) + for (cMobFamilyCollecter::tMobFamilyList::const_iterator itr = cMobFamilyCollecter::m_AllFamilies().begin(); itr != cMobFamilyCollecter::m_AllFamilies().end(); itr++) { - m_LastSpawnMonster[*itr] = m_WorldAge; - // each megatype of mob has it's own cap - if (!(MobCensus.IsCapped(*itr))) + int spawnrate = cMonster::GetSpawnRate(*itr); + if ( + (m_LastSpawnMonster[*itr] > m_WorldAge - spawnrate) || // Not reached the needed tiks before the next round + MobCensus.IsCapped(*itr) + ) { - if (m_bAnimals) + continue; + } + m_LastSpawnMonster[*itr] = m_WorldAge; + cMobSpawner Spawner(*itr, m_AllowedMobs); + if (Spawner.CanSpawnAnything()) + { + m_ChunkMap->SpawnMobs(Spawner); + // do the spawn + for(cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); itr2++) { - cMobSpawner Spawner(*itr,m_AllowedMobs); - if (Spawner.CanSpawnAnything()) - { - m_ChunkMap->SpawnMobs(Spawner); - // do the spawn - for(cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); itr2++) - { - SpawnMobFinalize(*itr2); - } - } + SpawnMobFinalize(*itr2); } - } - } - } + } + } // for itr - Families[] + } // if (Spawning enabled) // move close mobs cMobProximityCounter::sIterablePair allCloseEnoughToMoveMobs = MobCensus.GetProximityCounter().getMobWithinThosesDistances(-1, 64 * 16);// MG TODO : deal with this magic number (the 16 is the size of a block)