Skip to content

Commit 271b213

Browse files
authored
Merge pull request #315 from crymp-net/fix-tracermanager-hang
Fix tracermanager hang
2 parents 01eebc4 + 46dcc87 commit 271b213

File tree

4 files changed

+63
-30
lines changed

4 files changed

+63
-30
lines changed

Code/CryGame/Items/Weapons/Projectile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ void CProjectile::Destroy()
719719

720720
bool returnToPoolOK = true;
721721

722-
const bool reusable = m_pAmmoParams->flags & (ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_SERVER_ONLY);
722+
const bool reusable = g_pGameCVars->mp_recycleProjectiles && m_pAmmoParams->flags & (ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_SERVER_ONLY);
723723
if (reusable)
724724
{
725725
returnToPoolOK = g_pGame->GetWeaponSystem()->ReturnToPool(this);

Code/CryGame/Items/Weapons/TracerManager.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -182,31 +182,7 @@ void CTracerManager::EmitTracer(const STracerParams& params)
182182
if (!g_pGameCVars->g_enableTracers || !gEnv->bClient)
183183
return;
184184

185-
int idx = -1;
186-
const int poolSize = static_cast<int>(m_pool.size());
187-
int i = m_lastFree + 1;
188-
189-
while (true)
190-
{
191-
if (i >= poolSize) i = 0;
192-
if (i == m_lastFree)
193-
{
194-
m_pool.emplace_back(std::make_unique<CTracer>(params.position));
195-
idx = static_cast<int>(m_pool.size() - 1);
196-
break;
197-
}
198-
199-
IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_pool[i]->m_entityId);
200-
if (pEntity && pEntity->IsHidden())
201-
{
202-
m_pool[i]->Reset(params.position);
203-
idx = i;
204-
break;
205-
}
206-
++i;
207-
}
208-
209-
m_lastFree = idx;
185+
const size_t idx = CreateTracer(params);
210186
CTracer* tracer = m_pool[idx].get();
211187

212188
if (params.geometry && params.geometry[0])
@@ -229,7 +205,29 @@ void CTracerManager::EmitTracer(const STracerParams& params)
229205
pEntity->Hide(false);
230206
}
231207

232-
m_actives.push_back(idx);
208+
m_actives.push_back(static_cast<int>(idx));
209+
}
210+
211+
size_t CTracerManager::CreateTracer(const STracerParams& params)
212+
{
213+
IEntitySystem* pEntitySystem = gEnv->pEntitySystem;
214+
215+
// try to reuse an existing one
216+
for (size_t i = 0; i < m_pool.size(); i++)
217+
{
218+
IEntity* pEntity = pEntitySystem->GetEntity(m_pool[i]->m_entityId);
219+
if (pEntity && pEntity->IsHidden())
220+
{
221+
m_pool[i]->Reset(params.position);
222+
++m_numReused;
223+
return i;
224+
}
225+
}
226+
227+
// create a new one
228+
m_pool.emplace_back(std::make_unique<CTracer>(params.position));
229+
++m_numAllocated;
230+
return m_pool.size() - 1;
233231
}
234232

235233
void CTracerManager::Update(float frameTime)

Code/CryGame/Items/Weapons/TracerManager.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,37 @@ class CTracerManager
6868
};
6969

7070
void EmitTracer(const STracerParams& params);
71+
size_t CreateTracer(const STracerParams& params);
7172
void Update(float frameTime);
7273
void Reset();
7374
void GetMemoryStatistics(ICrySizer*);
7475

76+
size_t GetPoolSize() const
77+
{
78+
return m_pool.size();
79+
}
80+
81+
size_t GetActiveCount() const
82+
{
83+
return m_actives.size();
84+
}
85+
86+
unsigned int GetNumReused() const
87+
{
88+
return m_numReused;
89+
}
90+
91+
unsigned int GetNumAllocated() const
92+
{
93+
return m_numAllocated;
94+
}
95+
7596
private:
7697
std::vector<std::unique_ptr<CTracer>> m_pool;
7798
std::vector<int> m_updating;
7899
std::vector<int> m_actives;
79-
int m_lastFree = 0;
100+
unsigned int m_numReused = 0;
101+
unsigned int m_numAllocated = 0;
80102
};
81103

82104
#endif //__TRACERMANAGER_H__

Code/CryGame/Items/Weapons/WeaponSystem.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,7 @@ void CWeaponSystem::RemoveFromPool(CProjectile* pProjectile)
845845
return;
846846
}
847847

848-
std::erase_if(it->second.freeProjectiles, [&](const SmartProjectile& x) { return x.get() == pProjectile; });
849-
it->second.totalCount--;
848+
it->second.totalCount -= std::erase_if(it->second.freeProjectiles, [&](const SmartProjectile& x) { return x.get() == pProjectile; });
850849
}
851850

852851
//------------------------------------------------------------------------
@@ -863,6 +862,20 @@ void CWeaponSystem::DumpPoolSizes()
863862
CryLogAlways("%s: totalCount=%zu, freeCount=%zu", name, pool.totalCount, pool.freeProjectiles.size());
864863
}
865864

865+
CryLogAlways("------------------------ Tracer Manager Statistics -----------------------------");
866+
867+
CTracerManager& pTracerMgr = GetTracerManager();
868+
869+
const size_t total = pTracerMgr.GetPoolSize();
870+
const size_t actives = pTracerMgr.GetActiveCount();
871+
const unsigned int reused = pTracerMgr.GetNumReused();
872+
const unsigned int allocated = pTracerMgr.GetNumAllocated();
873+
874+
CryLogAlways("Total Allocated (in pool): %zu", total);
875+
CryLogAlways("Currently Active: %zu", actives);
876+
CryLogAlways("Reused: %u", reused);
877+
CryLogAlways("Newly Spawned: %u", allocated);
878+
866879
CryLogAlways("--------------------------------------------------------------------------------");
867880
}
868881

0 commit comments

Comments
 (0)