Add objects despawning in networking
This commit is contained in:
@@ -43,6 +43,12 @@ PACK_STRUCT(struct NetworkMessageSpawnObject
|
||||
char ObjectTypeName[128]; // TODO: introduce networked-name to synchronize unique names as ushort (less data over network)
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct NetworkMessageDespawnObject
|
||||
{
|
||||
NetworkMessageIDs ID = NetworkMessageIDs::SpawnObject;
|
||||
Guid ObjectId;
|
||||
});
|
||||
|
||||
struct NetworkReplicatedObject
|
||||
{
|
||||
ScriptingObjectReference<ScriptingObject> Object;
|
||||
@@ -93,6 +99,7 @@ namespace
|
||||
CriticalSection ObjectsLock;
|
||||
HashSet<NetworkReplicatedObject> Objects;
|
||||
Array<ScriptingObjectReference<ScriptingObject>> SpawnQueue;
|
||||
Array<Guid> DespawnQueue;
|
||||
Dictionary<Guid, Guid> IdsRemappingTable;
|
||||
NetworkStream* CachedWriteStream = nullptr;
|
||||
NetworkStream* CachedReadStream = nullptr;
|
||||
@@ -262,11 +269,32 @@ void NetworkReplicator::SpawnObject(ScriptingObject* obj)
|
||||
it = Objects.Find(obj->GetID());
|
||||
}
|
||||
|
||||
// Register for spawning (batched spawning during update)
|
||||
// Register for spawning (batched during update)
|
||||
ASSERT_LOW_LAYER(!SpawnQueue.Contains(obj));
|
||||
SpawnQueue.Add(obj);
|
||||
}
|
||||
|
||||
void NetworkReplicator::DespawnObject(ScriptingObject* obj)
|
||||
{
|
||||
if (!obj || NetworkManager::State == NetworkConnectionState::Offline)
|
||||
return;
|
||||
ScopeLock lock(ObjectsLock);
|
||||
const auto it = Objects.Find(obj->GetID());
|
||||
if (it == Objects.End())
|
||||
return;
|
||||
auto& item = it->Item;
|
||||
if (item.Object != obj || !item.Spawned || item.OwnerClientId != NetworkManager::LocalClientId)
|
||||
return;
|
||||
|
||||
// Register for despawning (batched during update)
|
||||
const Guid id = obj->GetID();
|
||||
ASSERT_LOW_LAYER(!DespawnQueue.Contains(id));
|
||||
DespawnQueue.Add(id);
|
||||
|
||||
// Prevent spawning
|
||||
SpawnQueue.Remove(obj);
|
||||
}
|
||||
|
||||
uint32 NetworkReplicator::GetObjectClientId(ScriptingObject* obj)
|
||||
{
|
||||
uint32 id = 0;
|
||||
@@ -389,6 +417,30 @@ void NetworkInternal::NetworkReplicatorUpdate()
|
||||
return;
|
||||
}
|
||||
|
||||
// Despawn
|
||||
if (DespawnQueue.Count() != 0)
|
||||
{
|
||||
PROFILE_CPU_NAMED("DespawnQueue");
|
||||
for (const Guid& e : DespawnQueue)
|
||||
{
|
||||
// Send despawn message
|
||||
NetworkMessageDespawnObject msgData;
|
||||
msgData.ObjectId = e;
|
||||
if (isClient)
|
||||
{
|
||||
// Remap local client object ids into server ids
|
||||
IdsRemappingTable.KeyOf(msgData.ObjectId, &msgData.ObjectId);
|
||||
}
|
||||
NetworkMessage msg = peer->BeginSendMessage();
|
||||
msg.WriteStructure(msgData);
|
||||
if (isClient)
|
||||
peer->EndSendMessage(NetworkChannelType::ReliableOrdered, msg);
|
||||
else
|
||||
peer->EndSendMessage(NetworkChannelType::ReliableOrdered, msg, CachedTargets);
|
||||
}
|
||||
DespawnQueue.Clear();
|
||||
}
|
||||
|
||||
// Spawn
|
||||
if (SpawnQueue.Count() != 0)
|
||||
{
|
||||
@@ -603,3 +655,32 @@ void NetworkInternal::OnNetworkMessageSpawnObject(NetworkEvent& event, NetworkCl
|
||||
// TODO: if we're server then spawn this object further on other clients
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkInternal::OnNetworkMessageDespawnObject(NetworkEvent& event, NetworkClient* client, NetworkPeer* peer)
|
||||
{
|
||||
NetworkMessageDespawnObject msgData;
|
||||
event.Message.ReadStructure(msgData);
|
||||
ScopeLock lock(ObjectsLock);
|
||||
NetworkReplicatedObject* e = ResolveObject(msgData.ObjectId);
|
||||
if (e)
|
||||
{
|
||||
auto& item = *e;
|
||||
ScriptingObject* obj = item.Object.Get();
|
||||
if (!obj || !item.Spawned)
|
||||
return;
|
||||
|
||||
// Reject despawn from someone who is not an object owner
|
||||
if (client && e->OwnerClientId != client->ClientId)
|
||||
return;
|
||||
|
||||
// Remove object
|
||||
Objects.Remove(obj);
|
||||
Delete(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NETWORK_REPLICATOR_DEBUG_LOG
|
||||
LOG(Error, "[NetworkReplicator] Failed to despawn object {}", msgData.ObjectId);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user