#include <unordered_set>
#include <algorithm>
#include <thread>
+#include <queue>
#include "Meta/Combine.hpp"
#include "Meta/Matching.hpp"
<b>This function should be called periodically to correctly handle
deletion of entities.</b>
- The map returned by this function lists all entities that have
+ The queue returned by this function lists all entities that have
changed as a result of calling this function.
- The size_t key refers to the original entity id of the entity,
- the bool value refers to whether or not the entity is still alive,
- and the size_t value refers to the new entity id if the entity
- is still alive.
+
+ The first parameter in the tuple (bool) is true if the entity has
+ been relocated (entity id has changed) and is false if the entity
+ has been deleted.
+
+ The second parameter (size_t) is the original entity id of the
+ entity. If the previous parameter was false for deleted, then this
+ refers to the id of that deleted entity. If the previous parameter
+ was true for relocated, then this refers to the previous id of the
+ relocated entity
+
+ The third parameter (size_t) is the new entity id of the entity if
+ the entity was relocated. If the entity was deleted then this
+ parameter is undefined as it is not used in that case.
*/
using CleanupReturnType =
- std::unordered_map<std::size_t, std::pair<bool, std::size_t> >;
+ std::queue<std::tuple<bool, std::size_t, std::size_t> >;
CleanupReturnType cleanup()
{
- CleanupReturnType changedMap;
+ CleanupReturnType changedQueue;
if(currentSize == 0)
{
- return changedMap;
+ return changedQueue;
}
std::size_t rhs = currentSize - 1;
if(rhs == 0)
{
currentSize = 0;
- return changedMap;
+ return changedQueue;
}
- changedMap.insert(std::make_pair(rhs, std::make_pair(
- false, 0)));
+ changedQueue.push(std::make_tuple(false, rhs, 0));
std::get<BitsetType>(entities[rhs]).reset();
--rhs;
}
// lhs is marked for deletion
// store deleted and changed id to map
- changedMap.insert(std::make_pair(lhs, std::make_pair(
- false, 0)));
- changedMap.insert(std::make_pair(rhs, std::make_pair(
- true, lhs)));
+ changedQueue.push(std::make_tuple(false, lhs, 0));
+ changedQueue.push(std::make_tuple(true, rhs, lhs));
// swap lhs entity with rhs entity
std::swap(entities[lhs], entities.at(rhs));
}
currentSize = rhs + 1;
- return changedMap;
+ return changedQueue;
}
/*!
auto e0 = manager.addEntity();
auto e1 = manager.addEntity();
auto e2 = manager.addEntity();
+ auto e3 = manager.addEntity();
manager.deleteEntity(e0);
+ manager.deleteEntity(e1);
- auto changedMap = manager.cleanup();
+ auto changedQueue = manager.cleanup();
- for(decltype(changedMap)::value_type& p : changedMap)
+ while(!changedQueue.empty())
{
- if(p.first == 0)
+ auto t = changedQueue.front();
+ if(std::get<1>(t) == 0)
+ {
+ EXPECT_FALSE(std::get<0>(t));
+ }
+ else if(std::get<1>(t) == 1)
{
- EXPECT_FALSE(p.second.first);
+ EXPECT_FALSE(std::get<0>(t));
}
- else if(p.first == 2)
+ else
{
- EXPECT_TRUE(p.second.first);
- EXPECT_EQ(0, p.second.second);
+ EXPECT_TRUE(std::get<0>(t));
}
+ changedQueue.pop();
}
EXPECT_FALSE(manager.hasEntity(2));
+ EXPECT_FALSE(manager.hasEntity(3));
EXPECT_TRUE(manager.hasEntity(0));
+ EXPECT_TRUE(manager.hasEntity(1));
}
TEST(EC, MultiThreaded)