Refactor most NetworkManager functionality into NetworkHost
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#include "Engine/Networking/NetworkConfig.h"
|
||||
#include "Engine/Networking/NetworkChannelType.h"
|
||||
#include "Engine/Networking/NetworkEvent.h"
|
||||
#include "Engine/Networking/NetworkManager.h"
|
||||
#include "Engine/Networking/NetworkHost.h"
|
||||
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
@@ -15,6 +15,7 @@
|
||||
#define ENET_IMPLEMENTATION
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
#include <enet/enet.h>
|
||||
|
||||
#undef _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
#undef SendMessage
|
||||
|
||||
@@ -52,8 +53,9 @@ void SendPacketToPeer(ENetPeer* peer, const NetworkChannelType channelType, cons
|
||||
// TODO: To reduce latency, we can use `enet_host_flush` to flush all packets. Maybe some API, like NetworkManager::FlushQueues()?
|
||||
}
|
||||
|
||||
void ENetDriver::Initialize(const NetworkConfig& config)
|
||||
void ENetDriver::Initialize(NetworkHost* host, const NetworkConfig& config)
|
||||
{
|
||||
_networkHost = host;
|
||||
_config = config;
|
||||
_peerMap = Dictionary<uint32_t, void*>();
|
||||
|
||||
@@ -202,7 +204,7 @@ bool ENetDriver::PopEvent(NetworkEvent* eventPtr)
|
||||
eventPtr->EventType = NetworkEventType::Message;
|
||||
|
||||
// Acquire message and copy message data
|
||||
eventPtr->Message = NetworkManager::CreateMessage(eventPtr->HostId);
|
||||
eventPtr->Message = _networkHost->CreateMessage();
|
||||
eventPtr->Message.Length = event.packet->dataLength;
|
||||
Memory::CopyItems(eventPtr->Message.Buffer, event.packet->data, event.packet->dataLength);
|
||||
break;
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
class NetworkHost;
|
||||
|
||||
API_CLASS(Namespace="FlaxEngine.Networking", Sealed) class FLAXENGINE_API ENetDriver : public INetworkDriver
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(ENetDriver);
|
||||
public:
|
||||
void Initialize(const NetworkConfig& config) override;
|
||||
void Initialize(NetworkHost* host, const NetworkConfig& config) override;
|
||||
void Dispose() override;
|
||||
|
||||
bool Listen() override;
|
||||
@@ -36,6 +38,7 @@ private:
|
||||
|
||||
private:
|
||||
NetworkConfig _config;
|
||||
NetworkHost* _networkHost;
|
||||
void* _host = nullptr;
|
||||
void* _peer = nullptr;
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
class NetworkHost;
|
||||
|
||||
API_INTERFACE(Namespace="FlaxEngine.Networking") class FLAXENGINE_API INetworkDriver
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(INetworkDriver);
|
||||
public:
|
||||
virtual void Initialize(const NetworkConfig& config) = 0;
|
||||
virtual void Initialize(NetworkHost* host, const NetworkConfig& config) = 0;
|
||||
virtual void Dispose() = 0;
|
||||
|
||||
virtual bool Listen() = 0;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkHost.h"
|
||||
#include "NetworkEvent.h"
|
||||
|
||||
|
||||
#include "Drivers/ENetDriver.h"
|
||||
|
||||
@@ -18,6 +20,7 @@ void NetworkHost::Initialize(const NetworkConfig& config)
|
||||
ASSERT(Config.MessageSize > 32); // TODO: Adjust this, not sure what the lowest limit should be.
|
||||
ASSERT(Config.MessagePoolSize > 128);
|
||||
|
||||
// TODO: Dynamic message pool allocation
|
||||
// Setup messages
|
||||
CreateMessageBuffers();
|
||||
MessagePool.Clear();
|
||||
@@ -28,7 +31,7 @@ void NetworkHost::Initialize(const NetworkConfig& config)
|
||||
|
||||
// Setup network driver
|
||||
NetworkDriver = New<ENetDriver>();
|
||||
NetworkDriver->Initialize(Config);
|
||||
NetworkDriver->Initialize(this, Config);
|
||||
|
||||
LOG(Info, "NetworkManager initialized using driver = {0}", static_cast<int>(Config.NetworkDriverType));
|
||||
}
|
||||
@@ -65,3 +68,94 @@ void NetworkHost::DisposeMessageBuffers()
|
||||
Platform::FreePages(MessageBuffer);
|
||||
MessageBuffer = nullptr;
|
||||
}
|
||||
|
||||
bool NetworkHost::Listen()
|
||||
{
|
||||
LOG(Info, "NetworkManager starting to listen on address = {0}:{1}", Config.Address, Config.Port);
|
||||
return NetworkDriver->Listen();
|
||||
}
|
||||
|
||||
bool NetworkHost::Connect()
|
||||
{
|
||||
LOG(Info, "Connecting to {0}:{1}...", Config.Address, Config.Port);
|
||||
return NetworkDriver->Connect();
|
||||
}
|
||||
|
||||
void NetworkHost::Disconnect()
|
||||
{
|
||||
LOG(Info, "Disconnecting...");
|
||||
NetworkDriver->Disconnect();
|
||||
}
|
||||
|
||||
void NetworkHost::Disconnect(const NetworkConnection& connection)
|
||||
{
|
||||
LOG(Info, "Disconnecting connection with id = {0}...", connection.ConnectionId);
|
||||
NetworkDriver->Disconnect(connection);
|
||||
}
|
||||
|
||||
bool NetworkHost::PopEvent(NetworkEvent& eventRef)
|
||||
{
|
||||
// Set host id of the event
|
||||
eventRef.HostId = HostId;
|
||||
return NetworkDriver->PopEvent(&eventRef);
|
||||
}
|
||||
|
||||
NetworkMessage NetworkHost::CreateMessage()
|
||||
{
|
||||
const uint32 messageId = MessagePool.Pop();
|
||||
uint8* messageBuffer = GetMessageBuffer(messageId);
|
||||
|
||||
return NetworkMessage(messageBuffer, messageId, Config.MessageSize, 0, 0);
|
||||
}
|
||||
|
||||
void NetworkHost::RecycleMessage(const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
#ifdef BUILD_DEBUG
|
||||
ASSERT(MessagePool.Contains(message.MessageId) == false);
|
||||
#endif
|
||||
|
||||
// Return the message id
|
||||
MessagePool.Push(message.MessageId);
|
||||
}
|
||||
|
||||
NetworkMessage NetworkHost::BeginSendMessage()
|
||||
{
|
||||
return CreateMessage();
|
||||
}
|
||||
|
||||
void NetworkHost::AbortSendMessage(const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
RecycleMessage(message);
|
||||
}
|
||||
|
||||
bool NetworkHost::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
NetworkDriver->SendMessage(channelType, message);
|
||||
|
||||
RecycleMessage(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkHost::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
NetworkDriver->SendMessage(channelType, message, target);
|
||||
|
||||
RecycleMessage(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkHost::EndSendMessage(const NetworkChannelType channelType, const NetworkMessage& message, Array<NetworkConnection> targets)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
NetworkDriver->SendMessage(channelType, message, targets);
|
||||
|
||||
RecycleMessage(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||
#include "Types.h"
|
||||
#include "NetworkConfig.h"
|
||||
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
|
||||
struct FLAXENGINE_API NetworkHost
|
||||
API_CLASS(sealed, NoSpawn, Namespace="FlaxEngine.Networking") class FLAXENGINE_API NetworkHost final : public PersistentScriptingObject
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkHost);
|
||||
friend class NetworkManager;
|
||||
public:
|
||||
int HostId;
|
||||
int HostId = -1;
|
||||
NetworkConfig Config;
|
||||
INetworkDriver* NetworkDriver = nullptr;
|
||||
|
||||
@@ -18,14 +22,59 @@ public:
|
||||
Array<uint32, HeapAllocation> MessagePool;
|
||||
|
||||
public:
|
||||
NetworkHost() : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void Initialize(const NetworkConfig& config);
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
void CreateMessageBuffers();
|
||||
void DisposeMessageBuffers();
|
||||
|
||||
public:
|
||||
API_FUNCTION()
|
||||
bool Listen();
|
||||
|
||||
API_FUNCTION()
|
||||
bool Connect();
|
||||
|
||||
API_FUNCTION()
|
||||
void Disconnect();
|
||||
|
||||
API_FUNCTION()
|
||||
void Disconnect(const NetworkConnection& connection);
|
||||
|
||||
API_FUNCTION()
|
||||
bool PopEvent(API_PARAM(out) NetworkEvent& eventRef);
|
||||
|
||||
API_FUNCTION()
|
||||
NetworkMessage CreateMessage();
|
||||
|
||||
API_FUNCTION()
|
||||
void RecycleMessage(const NetworkMessage& message);
|
||||
|
||||
API_FUNCTION()
|
||||
NetworkMessage BeginSendMessage();
|
||||
|
||||
API_FUNCTION()
|
||||
void AbortSendMessage(const NetworkMessage& message);
|
||||
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message);
|
||||
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target);
|
||||
|
||||
API_FUNCTION()
|
||||
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, Array<NetworkConnection, HeapAllocation> targets);
|
||||
|
||||
public:
|
||||
bool IsValid() const
|
||||
{
|
||||
return NetworkDriver != nullptr;
|
||||
return NetworkDriver != nullptr && HostId >= 0;
|
||||
}
|
||||
|
||||
uint8* GetMessageBuffer(const uint32 messageId) const
|
||||
|
||||
@@ -4,21 +4,17 @@
|
||||
|
||||
#include "NetworkMessage.h"
|
||||
#include "NetworkConfig.h"
|
||||
#include "NetworkConnection.h"
|
||||
#include "INetworkDriver.h"
|
||||
#include "NetworkEvent.h"
|
||||
#include "NetworkHost.h"
|
||||
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Array<NetworkHost, HeapAllocation> Hosts;
|
||||
Array<NetworkHost*, HeapAllocation> Hosts;
|
||||
}
|
||||
|
||||
int NetworkManager::Initialize(const NetworkConfig& config)
|
||||
NetworkHost* NetworkManager::CreateHost(const NetworkConfig& config)
|
||||
{
|
||||
// Validate the address for listen/connect
|
||||
NetworkEndPoint endPoint = {};
|
||||
@@ -27,142 +23,23 @@ int NetworkManager::Initialize(const NetworkConfig& config)
|
||||
|
||||
// Alloc new host
|
||||
const int hostId = Hosts.Count(); // TODO: Maybe keep the host count under a limit? Maybe some drivers do not support this?
|
||||
Hosts.Add(NetworkHost());
|
||||
NetworkHost& host = Hosts.Last();
|
||||
host.HostId = hostId;
|
||||
// TODO: Reuse host ids
|
||||
Hosts.Add(New<NetworkHost>());
|
||||
NetworkHost* host = Hosts.Last();
|
||||
host->HostId = hostId;
|
||||
|
||||
// Initialize the host
|
||||
host.Initialize(config);
|
||||
host->Initialize(config);
|
||||
|
||||
return hostId;
|
||||
return host;
|
||||
}
|
||||
|
||||
void NetworkManager::Shutdown(const int hostId)
|
||||
void NetworkManager::ShutdownHost(NetworkHost* host)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
host.Shutdown();
|
||||
ASSERT(host->IsValid());
|
||||
host->Shutdown();
|
||||
Hosts[host->HostId] = nullptr;
|
||||
host->HostId = -1;
|
||||
|
||||
// Hosts.Remove(host); // Do not remove hosts, because we need to keep the array unmodified to make the id's work
|
||||
}
|
||||
|
||||
bool NetworkManager::Listen(const int hostId)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
|
||||
LOG(Info, "NetworkManager starting to listen on address = {0}:{1}", host.Config.Address, host.Config.Port);
|
||||
|
||||
return host.NetworkDriver->Listen();
|
||||
}
|
||||
|
||||
bool NetworkManager::Connect(const int hostId)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
LOG(Info, "Connecting to {0}:{1}...", host.Config.Address, host.Config.Port);
|
||||
|
||||
return host.NetworkDriver->Connect();
|
||||
}
|
||||
|
||||
void NetworkManager::Disconnect(const int hostId)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
LOG(Info, "Disconnecting...");
|
||||
|
||||
host.NetworkDriver->Disconnect();
|
||||
}
|
||||
|
||||
void NetworkManager::Disconnect(const int hostId, const NetworkConnection& connection)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
LOG(Info, "Disconnecting connection with id = {0}...", connection.ConnectionId);
|
||||
|
||||
host.NetworkDriver->Disconnect(connection);
|
||||
}
|
||||
|
||||
bool NetworkManager::PopEvent(const int hostId, NetworkEvent& eventPtr)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
|
||||
// Set host id of the event
|
||||
eventPtr.HostId = hostId;
|
||||
|
||||
return host.NetworkDriver->PopEvent(&eventPtr);
|
||||
}
|
||||
|
||||
NetworkMessage NetworkManager::CreateMessage(const int hostId)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
ASSERT(host.MessagePool.Count() > 0);
|
||||
|
||||
const uint32 messageId = host.MessagePool.Pop();
|
||||
uint8* messageBuffer = host.GetMessageBuffer(messageId);
|
||||
|
||||
return NetworkMessage(messageBuffer, messageId, host.Config.MessageSize, 0, 0);
|
||||
}
|
||||
|
||||
void NetworkManager::RecycleMessage(const int hostId, const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
ASSERT(message.IsValid());
|
||||
#ifdef BUILD_DEBUG
|
||||
ASSERT(host.MessagePool.Contains(message.MessageId) == false);
|
||||
#endif
|
||||
|
||||
// Return the message id
|
||||
host.MessagePool.Push(message.MessageId);
|
||||
}
|
||||
|
||||
NetworkMessage NetworkManager::BeginSendMessage(const int hostId)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
return CreateMessage(hostId);
|
||||
}
|
||||
|
||||
void NetworkManager::AbortSendMessage(const int hostId, const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
ASSERT(message.IsValid());
|
||||
RecycleMessage(hostId, message);
|
||||
}
|
||||
|
||||
bool NetworkManager::EndSendMessage(const int hostId, const NetworkChannelType channelType, const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
host.NetworkDriver->SendMessage(channelType, message);
|
||||
|
||||
RecycleMessage(hostId, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkManager::EndSendMessage(const int hostId, const NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
host.NetworkDriver->SendMessage(channelType, message, target);
|
||||
|
||||
RecycleMessage(hostId, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetworkManager::EndSendMessage(const int hostId, const NetworkChannelType channelType, const NetworkMessage& message, const Array<NetworkConnection> targets)
|
||||
{
|
||||
ASSERT(Hosts[hostId].IsValid());
|
||||
NetworkHost& host = Hosts[hostId];
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
host.NetworkDriver->SendMessage(channelType, message, targets);
|
||||
|
||||
RecycleMessage(hostId, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,32 +5,14 @@
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Types.h"
|
||||
|
||||
class NetworkHost;
|
||||
|
||||
API_CLASS(Namespace="FlaxEngine.Networking", Static) class FLAXENGINE_API NetworkManager
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkManager);
|
||||
public:
|
||||
|
||||
API_FUNCTION() static int Initialize(const NetworkConfig& config);
|
||||
API_FUNCTION() static void Shutdown(int hostId);
|
||||
|
||||
API_FUNCTION() static bool Listen(int hostId);
|
||||
API_FUNCTION() static bool Connect(int hostId);
|
||||
API_FUNCTION() static void Disconnect(int hostId);
|
||||
API_FUNCTION() static void Disconnect(int hostId, const NetworkConnection& connection);
|
||||
|
||||
API_FUNCTION() static bool PopEvent(int hostId, API_PARAM(out) NetworkEvent& eventPtr);
|
||||
|
||||
API_FUNCTION() static NetworkMessage CreateMessage(int hostId);
|
||||
API_FUNCTION() static void RecycleMessage(int hostId, const NetworkMessage& message);
|
||||
|
||||
API_FUNCTION() static NetworkMessage BeginSendMessage(int hostId);
|
||||
API_FUNCTION() static void AbortSendMessage(int hostId, const NetworkMessage& message);
|
||||
API_FUNCTION() static bool EndSendMessage(int hostId, NetworkChannelType channelType, const NetworkMessage& message);
|
||||
API_FUNCTION() static bool EndSendMessage(int hostId, NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target);
|
||||
API_FUNCTION() static bool EndSendMessage(int hostId, NetworkChannelType channelType, const NetworkMessage& message, Array<NetworkConnection, HeapAllocation> targets);
|
||||
|
||||
// TODO: Stats API
|
||||
// TODO: Simulation API
|
||||
// TODO: Optimize 'targets' in EndSendMessage
|
||||
API_FUNCTION() static NetworkHost* CreateHost(const NetworkConfig& config);
|
||||
API_FUNCTION() static void ShutdownHost(NetworkHost* host);
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user