Eliminate needless indirection from TCP stack

This commit is contained in:
Joshua Ashton 2020-08-01 04:38:20 +01:00
parent cb72973db2
commit d4b8842c92
9 changed files with 120 additions and 120 deletions

View File

@ -19,7 +19,7 @@ namespace Feather
auto [clients, clientsLock] = m_clients.borrow();
for (auto& client : clients)
{
auto [data, clientLock] = client.GetTCPClient().GetData().borrow();
auto [data, clientLock] = client.GetTCPClient()->GetData().borrow();
if (data.empty())
continue;
auto reader = PacketReader(data.data());
@ -33,15 +33,15 @@ namespace Feather
{
}
void DedicatedServer::OnClientConnect(Network::TCPClient&& client)
void DedicatedServer::OnClientConnect(Network::TCPClientHandle&& client)
{
auto [clients, lock] = m_clients.borrow();
clients.emplace_back(std::move(client));
}
void DedicatedServer::OnClientDisconnect(const Network::TCPClient& client)
void DedicatedServer::OnClientDisconnect(const Network::TCPClientHandle& client)
{
auto [clients, lock] = m_clients.borrow();
clients.remove_if([&](MinecraftClient& other) { return &other.GetTCPClient() == &client; });
clients.remove_if([&](MinecraftClient& other) { return other.GetTCPClient() == client; });
}
}

View File

@ -16,8 +16,8 @@ namespace Feather
DedicatedServer(ServerProperties* properties);
~DedicatedServer();
void OnClientConnect(Network::TCPClient&& client) override;
void OnClientDisconnect(const Network::TCPClient& client) override;
void OnClientConnect(Network::TCPClientHandle&& client) override;
void OnClientDisconnect(const Network::TCPClientHandle& client) override;
ServerStatus& GetStatus() { return m_status; }

View File

@ -2,8 +2,8 @@
namespace Feather
{
MinecraftClient::MinecraftClient(Network::TCPClient&& client)
: m_client (std::move(client))
MinecraftClient::MinecraftClient(Network::TCPClientHandle&& client)
: m_client(std::move(client))
{
}
@ -13,6 +13,6 @@ namespace Feather
void MinecraftClient::SendMessage(const NetworkMessage& message)
{
m_client.Write(message.GetData(), message.GetDataSize());
m_client->Write(message.GetData(), message.GetDataSize());
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "network/TCPListener.h"
#include "network/TCPClient.h"
#include "Protocol.h"
#include "NetworkMessage.h"
@ -9,16 +10,16 @@ namespace Feather
class MinecraftClient
{
public:
MinecraftClient(Network::TCPClient&& client);
MinecraftClient(Network::TCPClientHandle&& client);
~MinecraftClient();
inline Network::TCPClient& GetTCPClient() { return m_client; }
inline Network::TCPClientHandle& GetTCPClient() { return m_client; }
inline ProtocolContext& GetContext() { return m_context; }
void SendMessage(const NetworkMessage& message);
private:
Network::TCPClient m_client;
ProtocolContext m_context;
Network::TCPClientHandle m_client;
ProtocolContext m_context;
};
}

View File

@ -1,15 +1,14 @@
#pragma once
#include "../Common.h"
#include "TCPCommon.h"
namespace Feather::Network
{
class TCPClient;
class abstract IListenerInterface
{
public:
virtual void OnClientConnect(TCPClient&& client) = 0;
virtual void OnClientDisconnect(const TCPClient& client) = 0;
virtual void OnClientConnect(TCPClientHandle&& client) = 0;
virtual void OnClientDisconnect(const TCPClientHandle& client) = 0;
};
}

32
src/network/TCPClient.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include "Lockable.h"
#include "TCPCommon.h"
#include <cstdint>
#include <vector>
namespace Feather::Network
{
class TCPClient
{
public:
TCPClient(TCPListener* parent, SocketHandle socket);
~TCPClient();
void ReadCallback();
void WriteCallback();
void EventCallback(int16_t event);
void Write(const uint8_t* data, size_t size);
LockableVector<uint8_t>& GetData();
private:
TCPListener* m_parent;
bufferevent* m_bufferEvent;
evbuffer* m_buffer;
LockableVector<uint8_t> m_data;
};
}

23
src/network/TCPCommon.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <memory>
struct bufferevent;
struct evbuffer;
namespace Feather::Network
{
#ifdef _WIN32
using SocketHandle = intptr_t;
#else
using SocketHandle = int;
#endif
class IListenerInterface;
class TCPListener;
class TCPSocket;
class TCPClient;
using TCPClientHandle = std::unique_ptr<TCPClient>;
}

View File

@ -4,6 +4,7 @@
#include "TCPListener.h"
#include "IListenerInterface.h"
#include "TCPClient.h"
#include "NetworkManager.h"
#include "NetworkMessage.h"
#include "PacketReader.h"
@ -102,101 +103,65 @@ namespace Feather::Network
return bind(m_socket, reinterpret_cast<const sockaddr*>(&name), sizeof(name)) == 0;
}
evutil_socket_t m_socket;
SocketHandle m_socket;
bool m_ipv6;
};
class TCPListenerClient
{
public:
TCPListenerClient(TCPListener* parent, evutil_socket_t socket)
: m_parent(parent)
, m_bufferEvent(bufferevent_socket_new(NetworkManager::Instance().GetEventBase(), socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS))
, m_buffer(evbuffer_new())
{
printf("Created TCPListenerClient\n");
bufferevent_setcb(m_bufferEvent,
[](bufferevent* be, void* self) { static_cast<TCPListenerClient*>(self)->ReadCallback(); },
[](bufferevent* be, void* self) { static_cast<TCPListenerClient*>(self)->WriteCallback(); },
[](bufferevent* be, short event, void* self) { static_cast<TCPListenerClient*>(self)->EventCallback(event); },
this);
bufferevent_enable(m_bufferEvent, EV_READ | EV_WRITE);
}
~TCPListenerClient()
{
evbuffer_free(m_buffer);
bufferevent_free(m_bufferEvent);
}
void ReadCallback()
{
if (bufferevent_read_buffer(m_bufferEvent, m_buffer) != 0)
{
printf("fuck");
return;
}
const size_t size = evbuffer_get_length(m_buffer);
auto [data, lock] = m_data.borrow();
data.resize(size);
if (evbuffer_remove(m_buffer, data.data(), size) != size)
{
printf("fuck");
return;
}
}
void WriteCallback()
{
}
void EventCallback(short event)
{
}
void Write(const uint8_t* data, size_t size)
{
if (bufferevent_write(m_bufferEvent, data, size) != 0)
printf("Fuck!");
}
LockableVector<uint8_t>& GetData()
{
return m_data;
}
private:
TCPListener* m_parent;
bufferevent* m_bufferEvent;
evbuffer* m_buffer;
LockableVector<uint8_t> m_data;
};
TCPClient::TCPClient(std::unique_ptr<TCPListenerClient>&& client)
: m_client(std::move(client))
{
}
TCPClient::TCPClient(TCPClient&& client)
: m_client(std::move(client.m_client))
TCPClient::TCPClient(TCPListener* parent, SocketHandle socket)
: m_parent(parent)
, m_bufferEvent(bufferevent_socket_new(NetworkManager::Instance().GetEventBase(), socket, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS))
, m_buffer(evbuffer_new())
{
printf("Created TCPListenerClient\n");
bufferevent_setcb(m_bufferEvent,
[](bufferevent* be, void* self) { static_cast<TCPClient*>(self)->ReadCallback(); },
[](bufferevent* be, void* self) { static_cast<TCPClient*>(self)->WriteCallback(); },
[](bufferevent* be, int16_t event, void* self) { static_cast<TCPClient*>(self)->EventCallback(event); },
this);
bufferevent_enable(m_bufferEvent, EV_READ | EV_WRITE);
}
TCPClient::~TCPClient()
{
evbuffer_free(m_buffer);
bufferevent_free(m_bufferEvent);
}
LockableVector<uint8_t>& TCPClient::GetData()
void TCPClient::ReadCallback()
{
if (bufferevent_read_buffer(m_bufferEvent, m_buffer) != 0)
{
printf("fuck");
return;
}
const size_t size = evbuffer_get_length(m_buffer);
auto [data, lock] = m_data.borrow();
data.resize(size);
if (evbuffer_remove(m_buffer, data.data(), size) != size)
{
printf("fuck");
return;
}
}
void TCPClient::WriteCallback()
{
}
void TCPClient::EventCallback(int16_t event)
{
return m_client->GetData();
}
void TCPClient::Write(const uint8_t* data, size_t size)
{
m_client->Write(data, size);
if (bufferevent_write(m_bufferEvent, data, size) != 0)
printf("Fuck!");
}
LockableVector<uint8_t>& TCPClient::GetData()
{
return m_data;
}
TCPListener::TCPListener(uint16_t port, IListenerInterface* callbacks)
@ -223,7 +188,7 @@ namespace Feather::Network
auto ListenerCallback = [](evconnlistener* evListener, evutil_socket_t socket, sockaddr* addr, int len, void* self)
{
TCPListener* listener = static_cast<TCPListener*>(self);
listener->m_callbacks->OnClientConnect(std::make_unique<TCPListenerClient>(listener, socket));
listener->m_callbacks->OnClientConnect(std::make_unique<TCPClient>(listener, socket));
};
if (!socket->Listen(ListenerCallback, this))

View File

@ -1,31 +1,12 @@
#pragma once
#include "Lockable.h"
#include "TCPCommon.h"
#include <cstdint>
#include <memory>
#include <vector>
namespace Feather::Network
{
class TCPSocket;
class TCPListenerClient;
class IListenerInterface;
class TCPClient
{
public:
TCPClient(std::unique_ptr<TCPListenerClient>&& client);
TCPClient(TCPClient&& client);
~TCPClient();
LockableVector<uint8_t>& GetData();
void Write(const uint8_t* data, size_t size);
private:
std::unique_ptr<TCPListenerClient> m_client;
};
{
class TCPListener
{
public:
@ -36,5 +17,4 @@ namespace Feather::Network
std::unique_ptr<TCPSocket> m_socket;
};
}