Add basic network classes and message pooling
This commit is contained in:
13
Source/Engine/Networking/INetworkDriver.h
Normal file
13
Source/Engine/Networking/INetworkDriver.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
API_INTERFACE() class FLAXENGINE_API INetworkDriver
|
||||
{
|
||||
public:
|
||||
virtual void Initialize(const NetworkConfig& config) = 0;
|
||||
virtual void Dispose() = 0;
|
||||
|
||||
virtual void Listen() = 0;
|
||||
virtual void SendMessage(const NetworkMessage* message, void* targets) = 0; // TODO
|
||||
};
|
||||
18
Source/Engine/Networking/NetworkChannelType.h
Normal file
18
Source/Engine/Networking/NetworkChannelType.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
API_ENUM() enum class NetworkChannelType
|
||||
{
|
||||
None = 0,
|
||||
|
||||
Unreliable,
|
||||
UnreliableOrdered,
|
||||
UnreliableFragmented,
|
||||
|
||||
Reliable,
|
||||
ReliableOrdered,
|
||||
ReliableFragmented
|
||||
};
|
||||
15
Source/Engine/Networking/NetworkConfig.h
Normal file
15
Source/Engine/Networking/NetworkConfig.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkConfig
|
||||
{
|
||||
public:
|
||||
INetworkDriver* NetworkDriver = nullptr;
|
||||
|
||||
public:
|
||||
uint16 ConnectionsLimit = 32;
|
||||
uint16 Port = 7777;
|
||||
uint16 MessageSize = 1500; // MTU
|
||||
uint16 MessagePoolSize = 2048; // (RX and TX)
|
||||
};
|
||||
4
Source/Engine/Networking/NetworkConnection.cpp
Normal file
4
Source/Engine/Networking/NetworkConnection.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkConnection.h"
|
||||
|
||||
11
Source/Engine/Networking/NetworkConnection.h
Normal file
11
Source/Engine/Networking/NetworkConnection.h
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkConnection
|
||||
{
|
||||
public:
|
||||
uint32 ConnectionId;
|
||||
};
|
||||
25
Source/Engine/Networking/NetworkEvent.h
Normal file
25
Source/Engine/Networking/NetworkEvent.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
API_ENUM() enum class NetworkEventType
|
||||
{
|
||||
Undefined = 0,
|
||||
|
||||
ConnectionRequest,
|
||||
Connected,
|
||||
Disconnected,
|
||||
Message,
|
||||
Error
|
||||
};
|
||||
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkEvent
|
||||
{
|
||||
public:
|
||||
API_FIELD();
|
||||
NetworkEventType EventType;
|
||||
|
||||
// TODO
|
||||
};
|
||||
135
Source/Engine/Networking/NetworkManager.cpp
Normal file
135
Source/Engine/Networking/NetworkManager.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkManager.h"
|
||||
|
||||
#include "NetworkMessage.h"
|
||||
#include "NetworkConfig.h"
|
||||
#include "INetworkDriver.h"
|
||||
|
||||
#include "Engine/Core/Core.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Platform/CPUInfo.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
NetworkConfig Config;
|
||||
INetworkDriver* NetworkDriver = nullptr;
|
||||
|
||||
uint8* MessageBuffer = nullptr;
|
||||
Array<uint32, HeapAllocation> MessagePool;
|
||||
}
|
||||
|
||||
bool NetworkManager::Initialize(const NetworkConfig& config)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
ASSERT(NetworkDriver == nullptr);
|
||||
ASSERT(Config.NetworkDriver);
|
||||
ASSERT(Config.ConnectionsLimit > 0);
|
||||
ASSERT(Config.MessageSize > 32); // TODO: Adjust this, not sure what the lowest limit should be.
|
||||
ASSERT(Config.MessagePoolSize > 128);
|
||||
|
||||
// Setup messages
|
||||
CreateMessageBuffers();
|
||||
MessagePool.Clear();
|
||||
MessagePool.Resize(Config.MessagePoolSize);
|
||||
|
||||
// Warmup message pool
|
||||
for(uint32 messageId = Config.MessagePoolSize; messageId > 0; messageId --)
|
||||
MessagePool.Push(messageId);
|
||||
|
||||
// Setup network driver
|
||||
NetworkDriver = Config.NetworkDriver;
|
||||
NetworkDriver->Initialize(Config);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkManager::Shutdown()
|
||||
{
|
||||
SAFE_DISPOSE(NetworkDriver);
|
||||
DisposeMessageBuffers();
|
||||
}
|
||||
|
||||
bool NetworkManager::Listen()
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetworkManager::Connect()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void NetworkManager::Disconnect()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
NetworkMessage NetworkManager::BeginSendMessage()
|
||||
{
|
||||
return CreateMessage();
|
||||
}
|
||||
|
||||
void NetworkManager::AbortSendMessage(const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
RecycleMessage(message);
|
||||
}
|
||||
|
||||
bool NetworkManager::EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, Array<NetworkConnection> targets)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
|
||||
// TODO: Send message
|
||||
|
||||
RecycleMessage(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
NetworkMessage NetworkManager::CreateMessage()
|
||||
{
|
||||
ASSERT(MessagePool.Count() > 0);
|
||||
|
||||
const uint32 messageId = MessagePool.Pop();
|
||||
uint8* messageBuffer = GetMessageBuffer(messageId);
|
||||
|
||||
return NetworkMessage { messageBuffer, Config.MessageSize, 0, 0 };
|
||||
}
|
||||
|
||||
void NetworkManager::RecycleMessage(const NetworkMessage& message)
|
||||
{
|
||||
ASSERT(message.IsValid());
|
||||
}
|
||||
|
||||
void NetworkManager::CreateMessageBuffers()
|
||||
{
|
||||
ASSERT(MessageBuffer == nullptr);
|
||||
|
||||
const uint32 pageSize = Platform::GetCPUInfo().PageSize;
|
||||
|
||||
// Calculate total size in bytes
|
||||
const uint64 totalSize = static_cast<uint64>(Config.MessagePoolSize) * Config.MessageSize;
|
||||
|
||||
// Calculate the amount of pages that we need
|
||||
const uint32 numPages = totalSize > pageSize ? Math::CeilToInt(totalSize / static_cast<double>(pageSize)) : 1;
|
||||
|
||||
MessageBuffer = static_cast<uint8*>(Platform::AllocatePages(numPages, pageSize));
|
||||
Platform::MemorySet(MessageBuffer, 0, numPages * pageSize);
|
||||
}
|
||||
|
||||
void NetworkManager::DisposeMessageBuffers()
|
||||
{
|
||||
ASSERT(MessageBuffer != nullptr);
|
||||
|
||||
Platform::FreePages(MessageBuffer);
|
||||
MessageBuffer = nullptr;
|
||||
}
|
||||
|
||||
uint8* NetworkManager::GetMessageBuffer(const uint32 messageId)
|
||||
{
|
||||
// Calculate and return the buffer slice using previously calculated slice.
|
||||
return MessageBuffer + Config.MessageSize * messageId;
|
||||
}
|
||||
34
Source/Engine/Networking/NetworkManager.h
Normal file
34
Source/Engine/Networking/NetworkManager.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Types.h"
|
||||
|
||||
API_CLASS(Static) class FLAXENGINE_API NetworkManager
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkManager);
|
||||
public:
|
||||
|
||||
API_FUNCTION() static bool Initialize(const NetworkConfig& config);
|
||||
API_FUNCTION() static void Shutdown();
|
||||
|
||||
API_FUNCTION() static bool Listen();
|
||||
API_FUNCTION() static void Connect();
|
||||
API_FUNCTION() static void Disconnect();
|
||||
|
||||
API_FUNCTION() static bool PopEvent(NetworkEvent* event);
|
||||
|
||||
API_FUNCTION() static NetworkMessage BeginSendMessage();
|
||||
API_FUNCTION() static void AbortSendMessage(const NetworkMessage& message);
|
||||
API_FUNCTION() static bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, Array<NetworkConnection, HeapAllocation> targets);
|
||||
|
||||
private:
|
||||
|
||||
static NetworkMessage CreateMessage();
|
||||
static void RecycleMessage(const NetworkMessage& message);
|
||||
|
||||
static void CreateMessageBuffers();
|
||||
static void DisposeMessageBuffers();
|
||||
static uint8* GetMessageBuffer(uint32 messageId);
|
||||
};
|
||||
29
Source/Engine/Networking/NetworkMessage.cpp
Normal file
29
Source/Engine/Networking/NetworkMessage.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "NetworkMessage.h"
|
||||
|
||||
void NetworkMessage::WriteBytes(uint8* bytes, const int numBytes)
|
||||
{
|
||||
ASSERT(Position + numBytes < BufferSize);
|
||||
Platform::MemoryCopy(Buffer + Position, bytes, numBytes);
|
||||
Position += numBytes;
|
||||
}
|
||||
|
||||
void NetworkMessage::ReadBytes(uint8* bytes, const int numBytes)
|
||||
{
|
||||
ASSERT(Position + numBytes < BufferSize);
|
||||
Platform::MemoryCopy(bytes, Buffer + Position, numBytes);
|
||||
Position += numBytes;
|
||||
}
|
||||
|
||||
void NetworkMessage::WriteUInt32(uint32 value)
|
||||
{
|
||||
WriteBytes(reinterpret_cast<uint8*>(&value), sizeof(uint32));
|
||||
}
|
||||
|
||||
uint32 NetworkMessage::ReadUInt32()
|
||||
{
|
||||
uint32 value = 0;
|
||||
ReadBytes(reinterpret_cast<uint8*>(&value), sizeof(uint32));
|
||||
return value;
|
||||
}
|
||||
35
Source/Engine/Networking/NetworkMessage.h
Normal file
35
Source/Engine/Networking/NetworkMessage.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkMessage
|
||||
{
|
||||
public:
|
||||
API_FIELD()
|
||||
uint8* Buffer;
|
||||
|
||||
API_FIELD()
|
||||
uint32 BufferSize;
|
||||
|
||||
API_FIELD()
|
||||
uint32 Length;
|
||||
|
||||
API_FIELD()
|
||||
uint32 Position;
|
||||
|
||||
public:
|
||||
API_FUNCTION() void WriteBytes(uint8* bytes, int numBytes);
|
||||
API_FUNCTION() void ReadBytes(uint8* bytes, int numBytes);
|
||||
|
||||
public:
|
||||
API_FUNCTION() void WriteUInt32(uint32 value); // TODO: Macro the shit out of this
|
||||
API_FUNCTION() uint32 ReadUInt32();
|
||||
|
||||
public:
|
||||
API_FUNCTION() bool IsValid() const
|
||||
{
|
||||
return Buffer != nullptr && BufferSize > 0;
|
||||
}
|
||||
};
|
||||
12
Source/Engine/Networking/Types.h
Normal file
12
Source/Engine/Networking/Types.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class NetworkChannelType;
|
||||
|
||||
class INetworkDriver;
|
||||
|
||||
struct NetworkEvent;
|
||||
struct NetworkConnection;
|
||||
struct NetworkMessage;
|
||||
struct NetworkConfig;
|
||||
Reference in New Issue
Block a user