Hello
I want to know more about how to effectively index players by ID.
Suppose I have a vector that store all players in one place (yes I can break them apart for ECS but for the purpose of the question I have them together):
struct player
{
unsigned int ID;
char name[32];
float xpos, ypos, zpos;
float xvel, yvel, zvel;
int health;
// more to come
};
std::vector<player> m_Players;
Each player has a unique ID of type unsigned int which can be anything. If there are 6 players and one of them has for some reason has the highest ID value: 9999, then I don't want to have an allocated array of players of size 9999 where 9993 of them are unused to address them directly by ID(myPlayer = m_Players[9999]). I want a array of players of size 6, and I want an array of indices mapping IDs to their position in the player array, such that I can access each player by ID. The reason I don't directly want to use a std::map<id,player> is that I want to effectively traverse the player array in another places.
std::unordered_map<unsigned int, unsigned int> m_Index;
bool update(const unsigned long ID, float xvel, float yvel, float zvel)
{
auto search = m_Index.find(ID);
if (search == m_Index.end())
return false;
auto index = search->second;
if(index >= m_Players.size())
return false;
auto& myPlayer = m_Players.at(index);
if(ID != myPlayer.ID)
return false;
myPlayer.xvel = xvel;
myPlayer.yvel = yvel;
myPlayer.zvel = zvel;
return true;
}
void advance(const float timeDelta)
{
for(auto& myPlayer : m_Players)
{
myPlayer.xpos += xvel*timeDelta;
myPlayer.ypos += yvel*timeDelta;
myPlayer.zpos += zvel*timeDelta;
}
}
/*
void advance_parallel(const float timeDelta)
{
parallel_for(auto& myPlayer : m_Players)
{
myPlayer.xpos += xvel*timeDelta;
myPlayer.ypos += yvel*timeDelta;
myPlayer.zpos += zvel*timeDelta;
}
}
*/
Now, different players can be in different situations, for example, some players might be culled away, some players might be on differnt teams and so on. So I want to know if index maps could be suitable for these purposes:
std::unordered_map<unsigned int, unsigned int> m_Index_inactivePlayers;
std::unordered_map<unsigned int, unsigned int> m_Index_renderablePlayers;
std::unordered_map<unsigned int, unsigned int> m_Index_redTeamPlayers;
std::unordered_map<unsigned int, unsigned int> m_Index_blueTeamPlayers;
void redTeamHealthBoost(int health)
{
for(auto& [ID, index] : m_Index_redTeamPlayers)
{
if(index >= m_Players.size())
continue;
auto& myPlayer = m_Players.at(index);
if(ID != myPlayer.ID)
continue;
myPlayer.health += health;
}
}
Any thoughts, input or comments is much appreciated.