Positional container: implemented Update
This commit is contained in:
@@ -107,6 +107,7 @@ public:
|
|||||||
m_Items.push_back(item);
|
m_Items.push_back(item);
|
||||||
auto coords = GetCoords(world_pos);
|
auto coords = GetCoords(world_pos);
|
||||||
m_Grid[coords.x()][coords.y()].push_back(item);
|
m_Grid[coords.x()][coords.y()].push_back(item);
|
||||||
|
m_ReverseGridLookup[item] = coords;
|
||||||
// TODO should we call Update instead?
|
// TODO should we call Update instead?
|
||||||
//Update(item);
|
//Update(item);
|
||||||
return true;
|
return true;
|
||||||
@@ -158,16 +159,29 @@ public:
|
|||||||
for (auto ptr : m_Items)
|
for (auto ptr : m_Items)
|
||||||
{
|
{
|
||||||
// TODO is this efficient? Maybe use const ref?
|
// TODO is this efficient? Maybe use const ref?
|
||||||
|
|
||||||
|
|
||||||
Update(ptr);
|
Update(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Update(std::shared_ptr<T> item) override
|
void Update(std::shared_ptr<T> item) override
|
||||||
{
|
{
|
||||||
auto coords = GetCoords(item->GetPosition());
|
coord_type current_coords = GetCoords(item->GetPosition());
|
||||||
|
coord_type last_known_coords = m_ReverseGridLookup[item];
|
||||||
|
if (current_coords == last_known_coords)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vector_wptr& vec = m_Grid[last_known_coords.x()][last_known_coords.y()];
|
||||||
// remove the old weak ptr from the map
|
// remove the old weak ptr from the map
|
||||||
|
vec.erase(std::remove_if(vec.begin(), vec.end(),
|
||||||
|
[&](const std::weak_ptr<T>& w)
|
||||||
|
{
|
||||||
|
return !w.owner_before(item) && !item.owner_before(w);
|
||||||
|
}),
|
||||||
|
vec.end());
|
||||||
// add new weak ptr to the map
|
// add new weak ptr to the map
|
||||||
m_Grid[coords.x()][coords.y()].push_back(item);
|
m_Grid[current_coords.x()][current_coords.y()].push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -196,6 +210,16 @@ private:
|
|||||||
WorldSize m_GridSize;
|
WorldSize m_GridSize;
|
||||||
WorldSize m_GridStep;
|
WorldSize m_GridStep;
|
||||||
size_t m_ChunksPerAxis;
|
size_t m_ChunksPerAxis;
|
||||||
|
// TODO it would be better to have vector<T> - contiguous memory, more cache-friendly?
|
||||||
std::vector<std::shared_ptr<T>> m_Items;
|
std::vector<std::shared_ptr<T>> m_Items;
|
||||||
grid_type m_Grid;
|
grid_type m_Grid;
|
||||||
|
|
||||||
|
// normal lookup: WorldPos -> coord_type -> vector_wptr -> std::shared_ptr<T>
|
||||||
|
// reverse lookup: std::shared_ptr<T> -> vector_wptr -> coord_type
|
||||||
|
// we need the reverse lookup because T.GetPosition() may change and we need to delete
|
||||||
|
// the old weak_ptr from vector_wptr (without iterating through all of them).
|
||||||
|
// Also it might be useful to have T -> location lookup
|
||||||
|
// Note: hash of std::shared_ptr<T> may give us trouble if we free the memory and new one points
|
||||||
|
// to the same location, maybe it would be better to hash the object itself?
|
||||||
|
std::unordered_map<std::shared_ptr<T>, coord_type> m_ReverseGridLookup;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user