Leviathan  0.8.0.0
Leviathan game engine
Leviathan::SendableSystem Class Reference

Sends updated entities from server to clients. More...

#include <Systems.h>

Public Member Functions

void Run (GameWorld &world, std::unordered_map< ObjectID, Sendable *> &index)
 

Protected Member Functions

DLLEXPORT void HandleNode (ObjectID id, Sendable &obj, GameWorld &world)
 

Detailed Description

Sends updated entities from server to clients.

Todo:
Change this to take distance into account don't send as many updates to clients far away

Definition at line 128 of file Systems.h.

Member Function Documentation

◆ HandleNode()

DLLEXPORT void SendableSystem::HandleNode ( ObjectID  id,
Sendable obj,
GameWorld world 
)
protected
Todo:
Something should be done with the required state allocation in this method

Definition at line 102 of file Systems.cpp.

103 {
104  const bool isServer = world.GetNetworkSettings().IsAuthoritative;
105 
106  const auto& players = world.GetConnectedPlayers();
107  const auto& serverConnection = world.GetServerForLocalControl();
108 
109  // Create current state here as one or more connections should require it //
110  // TODO: this could be removed entirely if we don't allow delta compression within a single
111  // component. Other possible approach is to recycle old captured state objects
112  auto curState = std::make_shared<EntityState>();
113 
114  world.CaptureEntityState(id, *curState);
115 
116  if(!curState) {
117 
118  LOG_ERROR(
119  "SendableSystem: created invalid state for entity, id: " + Convert::ToString(id));
120  return;
121  }
122 
123  // Detect successful packets and closed connections
124  for(auto iter = obj.UpdateReceivers.begin(); iter != obj.UpdateReceivers.end();) {
125  // This is closed if the connection is invalid
126  if(!iter->CorrespondingConnection->IsValidForSend()) {
127  iter = obj.UpdateReceivers.erase(iter);
128  continue;
129  }
130 
131  bool exists = false;
132 
133  if(isServer) {
134  // Or if the player has been removed from the world
135 
136  for(const auto& player : players) {
137 
138  if(iter->CorrespondingConnection == player->GetConnection()) {
139  exists = true;
140  break;
141  }
142  }
143  } else {
144 
145  if(iter->CorrespondingConnection == serverConnection)
146  exists = true;
147  }
148 
149  if(!exists) {
150  iter = obj.UpdateReceivers.erase(iter);
151  continue;
152  }
153 
154  // Check the most recent received state
155  iter->CheckReceivedPackets();
156 
157  // Still valid, move to next
158  ++iter;
159  }
160 
161  // Handle sending updates
162  if(isServer) {
163  for(const auto& player : players) {
164 
165  const auto& connection = player->GetConnection();
166 
167  SendableHandleHelper(id, obj, world, connection, curState, isServer);
168  }
169  } else {
170 
171  if(serverConnection && serverConnection->IsValidForSend()) {
172 
173  SendableHandleHelper(id, obj, world, serverConnection, curState, isServer);
174  }
175  }
176 }
std::vector< ActiveConnection > UpdateReceivers
Clients we have already sent a state to.
Definition: Components.h:159
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT const auto & GetNetworkSettings() const
Definition: GameWorld.h:345
DLLEXPORT const auto & GetServerForLocalControl() const
Definition: GameWorld.h:413
static std::string ToString(const T &val)
Definition: Convert.h:72
virtual DLLEXPORT void CaptureEntityState(ObjectID id, EntityState &curstate) const
Captures the current state of an entity.
Definition: GameWorld.cpp:520
const auto & GetConnectedPlayers() const
This is used by Sendable system to loop all players.
Definition: GameWorld.h:373
void SendableHandleHelper(ObjectID id, Sendable &obj, GameWorld &world, const std::shared_ptr< Connection > &connection, const std::shared_ptr< EntityState > &curstate, bool server)
Helper for SendableSystem::HandleNode to not have as much code duplication for client and server code...
Definition: Systems.cpp:19

◆ Run()

void Leviathan::SendableSystem::Run ( GameWorld world,
std::unordered_map< ObjectID, Sendable *> &  index 
)
inline
Precondition
Final states for entities have been created for current tick

Definition at line 131 of file Systems.h.

132  {
133  for(auto iter = index.begin(); iter != index.end(); ++iter) {
134 
135  auto& node = *iter->second;
136 
137  if(!node.Marked)
138  continue;
139 
140  HandleNode(iter->first, node, world);
141 
142  node.Marked = false;
143  }
144  }
DLLEXPORT void HandleNode(ObjectID id, Sendable &obj, GameWorld &world)
Definition: Systems.cpp:102

The documentation for this class was generated from the following files: