Remade Snapshot logic from component based to entity based.

This commit is contained in:
Jocke
2016-01-23 16:40:38 +01:00
parent 31e7340daf
commit 2bf0434bcb
3 changed files with 85 additions and 84 deletions
+1
View File
@@ -64,6 +64,7 @@ private:
void send(Packet& packet); void send(Packet& packet);
void broadcast(Packet& packet); void broadcast(Packet& packet);
void sendSnapshot(); void sendSnapshot();
void addChildrenToPacket(Packet& packet, EntityID entityID);
void sendPing(); void sendPing();
void checkForTimeOuts(); void checkForTimeOuts();
void disconnect(UserID user); void disconnect(UserID user);
+37 -53
View File
@@ -7,13 +7,13 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService)
{ {
Network::initialize(); Network::initialize();
// Asumes root node is EntityID 0 // Asumes root node is EntityID_Invalid
insertIntoServerClientMaps(0, 0); insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
// Init timer // Init timer
m_TimeSinceSentInputs = std::clock(); m_TimeSinceSentInputs = std::clock();
// Default is local host // Default is local host
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1"); std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
int port = config->Get<int>("Networking.Port", 13); int port = config->Get<int>("Networking.Port", 27666);
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
// Set up network stream // Set up network stream
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter"); m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
@@ -176,66 +176,50 @@ void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, co
void Client::parseSnapshot(Packet& packet) void Client::parseSnapshot(Packet& packet)
{ {
std::string componentType = packet.ReadString();
while (packet.DataReadSize() < packet.Size()) { while (packet.DataReadSize() < packet.Size()) {
// HACK EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
std::string entityName = packet.ReadString(); EntityID serverParentID = packet.ReadPrimitive<EntityID>();
// Components EntityID std::string serverEntityName = packet.ReadString();
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>(); int ammountOfComponents = packet.ReadPrimitive<int>();
// HACK for (int i = 0; i < ammountOfComponents; i++) {
m_World->SetName(receivedEntityID, entityName); std::string componentType = packet.ReadString();
// Parents EntityID
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
// Check if the received EntityID is mapped to one of our local EntityIDs if (serverClientMapsHasEntity(serverEntityID)) {
if (serverClientMapsHasEntity(receivedEntityID)) { EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
// Get the local EntityID // Update entity
EntityID entityID = m_ServerIDToClientID.at(receivedEntityID); if (m_World->HasComponent(localEntityID, componentType)) {
// Check if the component exists // Update component
if (m_World->HasComponent(entityID, componentType)) {
// If the entity and the component exists update it
if (componentType == "Transform") { if (componentType == "Transform") {
InterpolateFields(packet, componentInfo, entityID, componentType); // Interpolate only transform components
InterpolateFields(packet, componentInfo, localEntityID, componentType);
} else { } else {
updateFields(packet, componentInfo, entityID, componentType); // Set component values
updateFields(packet, componentInfo, localEntityID, componentType);
} }
// if entity exists but not the component
} else { } else {
// Create component // Has entity but no component
m_World->AttachComponent(entityID, componentType); m_World->AttachComponent(localEntityID, componentType);
// Copy data to newly created component updateFields(packet, componentInfo, localEntityID, componentType);
updateFields(packet, componentInfo, entityID, componentType);
} }
// If the entity dosent exist nor the component
} else { } else {
// Create Entity // Create Entity and component
// If entity dosen't exist EntityID newLocalEntityID;
EntityID newEntityID = m_World->CreateEntity(); if (serverParentID == EntityID_Invalid) {
insertIntoServerClientMaps(receivedEntityID, newEntityID); newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
// Check if EntityIDs are out of sync
if (newEntityID != receivedEntityID) {
LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the \
same as the one sent by server (EntityIDs are out of sync)");
}
// Create component
m_World->AttachComponent(newEntityID, componentType);
// Copy data to newly created component
updateFields(packet, componentInfo, newEntityID, componentType);
}
// Parent Logic
// Don't need to check if receivedEntityID is mapped. (It should have been set)
if (receivedParentEntityID != std::numeric_limits<EntityID>::max()) {
if (serverClientMapsHasEntity(receivedParentEntityID)) {
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), m_ServerIDToClientID.at(receivedParentEntityID));
// If Parent dosen't exist create one and map receivedParentEntityID to it.
} else { } else {
// Create the new parent and add it to map newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
EntityID newParentEntityID = m_World->CreateEntity();
insertIntoServerClientMaps(receivedParentEntityID, newParentEntityID);
// Set the newly created Entity as parent.
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), newParentEntityID);
} }
m_World->SetName(newLocalEntityID, serverEntityName);
insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
m_World->AttachComponent(newLocalEntityID, componentType);
updateFields(packet, componentInfo, newLocalEntityID, componentType);
}
}
// Parent logic
// This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
if (serverParentID != EntityID_Invalid) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
} }
} }
} }
+32 -16
View File
@@ -175,24 +175,40 @@ void Server::broadcast(Packet& packet)
// Send snapshot fields // Send snapshot fields
void Server::sendSnapshot() void Server::sendSnapshot()
{ {
// Should time this
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
for (auto& it : worldComponentPools) {
Packet packet(MessageType::Snapshot); Packet packet(MessageType::Snapshot);
ComponentPool* componentPool = it.second; addChildrenToPacket(packet, EntityID_Invalid);
ComponentInfo componentInfo = componentPool->ComponentInfo(); broadcast(packet);
}
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{
auto itPair = m_World->GetChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
// Write EntityID and parentsID and Entity name
packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
packet.WriteString(m_World->GetName(childEntityID));
// Write components to child
int numberOfComponents = 0;
for (auto& i : worldComponentPools) {
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
}
}
// Write how many components should be read
packet.WritePrimitive(numberOfComponents);
for (auto& i : worldComponentPools) {
// If the entity exist in the pool
if (i.second->KnowsEntity(childEntityID)) {
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
// ComponentType // ComponentType
packet.WriteString(componentInfo.Name); packet.WriteString(componentWrapper.Info.Name);
for (auto& componentWrapper : *componentPool) { // Loop through fields
// HACK: Send entity name
packet.WriteString(m_World->GetName(componentWrapper.EntityID));
// Components EntityID
packet.WritePrimitive(componentWrapper.EntityID);
// Parents EntityID
packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID));
for (auto& componentField : componentWrapper.Info.FieldsInOrder) { for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField); ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
if (fieldInfo.Type == "string") { if (fieldInfo.Type == "string") {
std::string& value = componentWrapper[componentField]; std::string& value = componentWrapper[componentField];
packet.WriteString(value); packet.WriteString(value);
@@ -201,9 +217,9 @@ void Server::sendSnapshot()
} }
} }
} }
if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) {
broadcast(packet);
} }
// Go to to your children
addChildrenToPacket(packet, childEntityID);
} }
} }