Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions Client/mods/deathmatch/logic/CClientStreamSector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,24 +137,32 @@ void CClientStreamSector::CompareSurroundings(CClientStreamSector* pSector, list
}
}

void CClientStreamSector::AddElements(list<CClientStreamElement*>* pList)
void CClientStreamSector::AddElements(list<CClientStreamElement*>* pList, std::unordered_set<CClientStreamElement*>* pSet)
{
list<CClientStreamElement*>::iterator iter = m_Elements.begin();
for (; iter != m_Elements.end(); iter++)
{
// Don't add if already in the list
if (ListContains(*pList, *iter))
// Don't add if already in the list (O(1) if set provided)
if (pSet)
{
if (pSet->count(*iter))
continue;
pSet->insert(*iter);
}
else if (ListContains(*pList, *iter))
continue;

pList->push_back(*iter);
}
}

void CClientStreamSector::RemoveElements(list<CClientStreamElement*>* pList)
void CClientStreamSector::RemoveElements(list<CClientStreamElement*>* pList, std::unordered_set<CClientStreamElement*>* pSet)
{
list<CClientStreamElement*>::iterator iter = m_Elements.begin();
for (; iter != m_Elements.end(); iter++)
{
pList->remove(*iter);
if (pSet)
pSet->erase(*iter);
}
}
5 changes: 3 additions & 2 deletions Client/mods/deathmatch/logic/CClientStreamSector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#pragma once

#include <list>
#include <unordered_set>
#include "CClientCommon.h"

class CClientStreamer;
Expand Down Expand Up @@ -38,8 +39,8 @@ class CClientStreamSector
std::list<CClientStreamElement*>::iterator Begin() { return m_Elements.begin(); }
std::list<CClientStreamElement*>::iterator End() { return m_Elements.end(); }

void AddElements(std::list<CClientStreamElement*>* pList);
void RemoveElements(std::list<CClientStreamElement*>* pList);
void AddElements(std::list<CClientStreamElement*>* pList, std::unordered_set<CClientStreamElement*>* pSet = nullptr);
void RemoveElements(std::list<CClientStreamElement*>* pList, std::unordered_set<CClientStreamElement*>* pSet = nullptr);
unsigned int CountElements() { return m_Elements.size(); }

CClientStreamSectorRow* GetRow() { return m_pRow; }
Expand Down
86 changes: 31 additions & 55 deletions Client/mods/deathmatch/logic/CClientStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ CClientStreamer::~CClientStreamer()
m_WorldRows.clear();

// Clear our extra rows
iter = m_ExtraRows.begin();
for (; iter != m_ExtraRows.end(); iter++)
for (auto& [key, pRow] : m_ExtraRows)
{
delete *iter;
delete pRow;
}
m_ExtraRows.clear();
}
Expand Down Expand Up @@ -244,24 +243,21 @@ CClientStreamSectorRow* CClientStreamer::FindOrCreateRow(CVector& vecPosition, C
}
}

// Search through our extra rows
iter = m_ExtraRows.begin();
for (; iter != m_ExtraRows.end(); iter++)
{
pRow = *iter;
if (pRow->DoesContain(vecPosition))
{
return pRow;
}
}
// We need a new row, align it with the others
// Search through our extra rows using map lookup
float fBottom = float((int)(vecPosition.fY / m_fRowSize)) * m_fRowSize;
if (vecPosition.fY < 0.0f)
fBottom -= m_fRowSize;
int iRowIndex = (int)(fBottom / m_fRowSize);

auto it = m_ExtraRows.find(iRowIndex);
if (it != m_ExtraRows.end())
return it->second;

// We need a new row, align it with the others
pRow = new CClientStreamSectorRow(fBottom, fBottom + m_fRowSize, m_fSectorSize, m_fRowSize);
ConnectRow(pRow);
pRow->SetExtra(true);
m_ExtraRows.push_back(pRow);
m_ExtraRows[iRowIndex] = pRow;
return pRow;
}

Expand All @@ -279,16 +275,16 @@ CClientStreamSectorRow* CClientStreamer::FindRow(float fY)
}
}

// Search through our extra rows
iter = m_ExtraRows.begin();
for (; iter != m_ExtraRows.end(); iter++)
{
pRow = *iter;
if (pRow->DoesContain(fY))
{
return pRow;
}
}
// Search through our extra rows using map lookup
float fBottom = float((int)(fY / m_fRowSize)) * m_fRowSize;
if (fY < 0.0f)
fBottom -= m_fRowSize;
int iRowIndex = (int)(fBottom / m_fRowSize);

auto it = m_ExtraRows.find(iRowIndex);
if (it != m_ExtraRows.end())
return it->second;

return NULL;
}

Expand Down Expand Up @@ -333,6 +329,7 @@ void CClientStreamer::RemoveElement(CClientStreamElement* pElement)
{
OnElementEnterSector(pElement, NULL);
m_ActiveElements.remove(pElement);
m_ActiveElementSet.erase(pElement);
m_ToStreamOut.remove(pElement);
}

Expand All @@ -355,27 +352,14 @@ void CClientStreamer::AddToSortedList(list<CClientStreamElement*>* pList, CClien
float fDistance = pElement->GetDistanceToBoundingBoxSquared(m_vecPosition);
pElement->SetExpDistance(fDistance);

// Don't add if already in the list
if (ListContains(*pList, pElement))
// Don't add if already in the list (O(1) check)
if (m_ActiveElementSet.count(pElement))
return;

// Search through our list. Add it behind the first item further away than this
CClientStreamElement* pTemp = NULL;
list<CClientStreamElement*>::iterator iter = pList->begin();
for (; iter != pList->end(); iter++)
{
pTemp = *iter;

// Is it further than the one we add?
if (pTemp->GetDistanceToBoundingBoxSquared(m_vecPosition) > fDistance)
{
// Add it before here
pList->insert(iter, pElement);
return;
}
}
// Track in the set
m_ActiveElementSet.insert(pElement);

// We have no elements in the list, add it at the beginning
// Append unsorted - DoPulse sorts the list every frame via m_ActiveElements.sort()
pList->push_back(pElement);
}

Expand All @@ -386,15 +370,7 @@ bool CClientStreamer::CompareExpDistance(CClientStreamElement* p1, CClientStream

bool CClientStreamer::IsActiveElement(CClientStreamElement* pElement)
{
list<CClientStreamElement*>::iterator iter = m_ActiveElements.begin();
for (; iter != m_ActiveElements.end(); iter++)
{
if (*iter == pElement)
{
return true;
}
}
return false;
return m_ActiveElementSet.count(pElement) > 0;
}

void CClientStreamer::Restream(bool bMovedFar)
Expand Down Expand Up @@ -650,7 +626,7 @@ void CClientStreamer::OnEnterSector(CClientStreamSector* pSector)
m_ToStreamOut.push_back(pElement);
}
}
pTempSector->RemoveElements(&m_ActiveElements);
pTempSector->RemoveElements(&m_ActiveElements, &m_ActiveElementSet);
pTempSector->SetActivated(false);
}
}
Expand All @@ -666,7 +642,7 @@ void CClientStreamer::OnEnterSector(CClientStreamSector* pSector)
pTempSector = *iter;
if (!pTempSector->IsActivated())
{
pTempSector->AddElements(&m_ActiveElements);
pTempSector->AddElements(&m_ActiveElements, &m_ActiveElementSet);
pTempSector->SetActivated(true);
}
}
Expand Down Expand Up @@ -708,7 +684,7 @@ void CClientStreamer::OnElementEnterSector(CClientStreamElement* pElement, CClie
// Should we activate this sector?
if (pSector->IsExtra() && (m_pSector->IsMySurroundingSector(pSector) || m_pSector == pSector))
{
pSector->AddElements(&m_ActiveElements);
pSector->AddElements(&m_ActiveElements, &m_ActiveElementSet);
pSector->SetActivated(true);
}
// If we're in a deactivated sector and streamed in, stream us out
Expand Down
29 changes: 16 additions & 13 deletions Client/mods/deathmatch/logic/CClientStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "CClientCommon.h"
#include <list>
#include <unordered_map>
#include <unordered_set>
class CClientStreamSector;
class CClientStreamSectorRow;
class CClientStreamElement;
Expand Down Expand Up @@ -61,19 +63,20 @@ class CClientStreamer
void OnElementForceStreamOut(CClientStreamElement* pElement);
void OnElementDimension(CClientStreamElement* pElement);

const float m_fSectorSize;
const float m_fRowSize;
float m_fMaxDistanceExp;
float m_fMaxDistanceThreshold;
StreamerLimitReachedFunction* m_pLimitReachedFunc;
std::list<CClientStreamSectorRow*> m_WorldRows;
std::list<CClientStreamSectorRow*> m_ExtraRows;
CClientStreamSectorRow* m_pRow;
CClientStreamSector* m_pSector;
CVector m_vecPosition;
unsigned short m_usDimension;
std::list<CClientStreamElement*> m_ActiveElements;
std::list<CClientStreamElement*> m_ToStreamOut;
const float m_fSectorSize;
const float m_fRowSize;
float m_fMaxDistanceExp;
float m_fMaxDistanceThreshold;
StreamerLimitReachedFunction* m_pLimitReachedFunc;
std::list<CClientStreamSectorRow*> m_WorldRows;
std::unordered_map<int, CClientStreamSectorRow*> m_ExtraRows;
CClientStreamSectorRow* m_pRow;
CClientStreamSector* m_pSector;
CVector m_vecPosition;
unsigned short m_usDimension;
std::list<CClientStreamElement*> m_ActiveElements;
std::unordered_set<CClientStreamElement*> m_ActiveElementSet;
std::list<CClientStreamElement*> m_ToStreamOut;

static void* pAddingElement;
};
Loading