High Level API - Fully Functional
This commit is contained in:
33
include/HLAPI/BitConverter.hpp
Normal file
33
include/HLAPI/BitConverter.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
// i want to use bitshifting but i red in stackoverflow that casting doesnt generate overhead
|
||||
// now ive hit a wall
|
||||
// casting vs bitshifting
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace std
|
||||
{
|
||||
class BitConverter
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
inline static uint8_t *ToBytes(T value)
|
||||
{
|
||||
uint8_t *data = new uint8_t[sizeof(T)]();
|
||||
memcpy(data, &value, sizeof(T));
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T FromBytes(uint8_t *data)
|
||||
{
|
||||
if (!data)
|
||||
throw std::invalid_argument("cant have null parameter -> BitConverter::FromBytes");
|
||||
T value;
|
||||
memcpy(&value, data, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
27
include/HLAPI/DataReceivedEvent.hpp
Normal file
27
include/HLAPI/DataReceivedEvent.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class DataReceivedEvent
|
||||
{
|
||||
public:
|
||||
inline DataReceivedEvent(const NetworkMessage &msg)
|
||||
{
|
||||
SenderID = msg.GetSenderID();
|
||||
DistributionMode = msg.GetDistributionMode();
|
||||
DestinationID = msg.GetDestinationID();
|
||||
Tag = msg.GetTag();
|
||||
Data = msg.GetData<void>();
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t SenderID;
|
||||
DistributionMode DistributionMode;
|
||||
uint32_t DestinationID;
|
||||
uint32_t Tag;
|
||||
|
||||
void *Data;
|
||||
};
|
||||
}
|
||||
36
include/HLAPI/DisconnectedEvent.hpp
Normal file
36
include/HLAPI/DisconnectedEvent.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class DisconnectedEvent // can be processed by client and server
|
||||
{
|
||||
private:
|
||||
DisconnectedEvent();
|
||||
|
||||
public:
|
||||
inline DisconnectedEvent(uint32_t id, char *reason, int32_t reason_id)
|
||||
: m_reason(reason)
|
||||
, m_clientID(id)
|
||||
, m_reasonID(reason_id)
|
||||
{
|
||||
}
|
||||
|
||||
inline DisconnectedEvent(uint32_t id, const std::string &reason, int32_t reason_id)
|
||||
: m_reason(reason)
|
||||
, m_clientID(id)
|
||||
, m_reasonID(reason_id)
|
||||
{
|
||||
}
|
||||
|
||||
inline const std::string &GetReason() const { return m_reason; }
|
||||
inline int32_t GetReasonID() const { return m_reasonID; }
|
||||
inline uint32_t GetID() const { return m_clientID; }
|
||||
|
||||
private:
|
||||
std::string m_reason;
|
||||
int32_t m_reasonID;
|
||||
uint32_t m_clientID;
|
||||
};
|
||||
}
|
||||
10
include/HLAPI/InternalTags.hpp
Normal file
10
include/HLAPI/InternalTags.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class InternalTags : uint32_t
|
||||
{
|
||||
Disconnect = 0xFFFFFFFF,
|
||||
Connect = 0xFFFFFFFE,
|
||||
AssignID = 0xFFFFFFFD
|
||||
};
|
||||
43
include/HLAPI/MessageQueue.hpp
Normal file
43
include/HLAPI/MessageQueue.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
#include "NewConnectionEvent.hpp"
|
||||
#include "DisconnectedEvent.hpp"
|
||||
#include "DataReceivedEvent.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class MessageQueue
|
||||
{
|
||||
public:
|
||||
MessageQueue()
|
||||
{
|
||||
}
|
||||
|
||||
void EnqueueMessageToSend(const NetworkMessage &msg);
|
||||
|
||||
void EnqueueMessageReceived(const NetworkMessage &msg);
|
||||
void EnqueueDisconnection(const NetworkMessage &msg);
|
||||
void EnqueueConnection(const NetworkMessage &msg);
|
||||
|
||||
NetworkMessage DequeueMessageToSend();
|
||||
|
||||
uint32_t SendSize();
|
||||
|
||||
private:
|
||||
std::deque<NetworkMessage> m_messagesToSend;
|
||||
|
||||
std::deque<NewConnectionEvent> m_connectionEvents;
|
||||
std::deque<DisconnectedEvent> m_disconnectedEvents;
|
||||
std::deque<DataReceivedEvent> m_dataReceivedEvents;
|
||||
|
||||
std::mutex m_sendMutex;
|
||||
std::mutex m_receivedMutex;
|
||||
std::mutex m_disconnectMutex;
|
||||
std::mutex m_connectionMutex;
|
||||
};
|
||||
}
|
||||
12
include/HLAPI/NetworkHeader.hpp
Normal file
12
include/HLAPI/NetworkHeader.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class NetworkHeader
|
||||
{
|
||||
public:
|
||||
uint32_t Size;
|
||||
};
|
||||
}
|
||||
95
include/HLAPI/NetworkMessage.hpp
Normal file
95
include/HLAPI/NetworkMessage.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetworkHeader.hpp"
|
||||
#include "BitConverter.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
enum class DistributionMode : uint8_t
|
||||
{
|
||||
ID,
|
||||
Others,
|
||||
OthersAndServer,
|
||||
All,
|
||||
AllAndMe,
|
||||
Server
|
||||
};
|
||||
|
||||
class NetworkMessage
|
||||
{
|
||||
public:
|
||||
NetworkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkMessage(uint32_t sender, DistributionMode mode, uint32_t destinationId, uint32_t tag, void *data, uint32_t dataSize)
|
||||
: m_senderID(sender)
|
||||
, m_distributionMode(mode)
|
||||
, m_destinationID(destinationId)
|
||||
, m_tag(tag)
|
||||
, m_data(data)
|
||||
, m_dataSize(dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t GetSenderID() const;
|
||||
DistributionMode GetDistributionMode() const;
|
||||
uint32_t GetDestinationID() const;
|
||||
uint32_t GetTag() const;
|
||||
|
||||
private:
|
||||
uint32_t m_senderID = 0;
|
||||
DistributionMode m_distributionMode = DistributionMode::All;
|
||||
uint32_t m_destinationID = 0;
|
||||
uint32_t m_tag = 0;
|
||||
|
||||
void *m_data = 0;
|
||||
uint32_t m_dataSize = 0;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
void SetData(T *data)
|
||||
{
|
||||
m_data = data;
|
||||
m_dataSize = sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
uint8_t * SerializeData(uint32_t &size)
|
||||
{
|
||||
int32_t sizeOfNetHeader = sizeof(NetworkHeader);
|
||||
|
||||
NetworkHeader header;
|
||||
header.Size = 13 + sizeOfNetHeader + sizeof(T);
|
||||
|
||||
uint8_t *bytes = new uint8_t[header.Size];
|
||||
memcpy(bytes, &header, sizeOfNetHeader);
|
||||
|
||||
uint8_t *sender = BitConverter::ToBytes<uint32_t>(m_senderID); // 4
|
||||
uint8_t *destination = BitConverter::ToBytes<uint32_t>(m_destinationID); // 4
|
||||
uint8_t *tag = BitConverter::ToBytes<uint32_t>(m_tag); // 4
|
||||
|
||||
memcpy(bytes + sizeOfNetHeader, sender, 4);
|
||||
bytes[sizeOfNetHeader + 4] = (uint8_t)m_distributionMode;
|
||||
memcpy(bytes + sizeOfNetHeader + 5, destination, 4);
|
||||
memcpy(bytes + sizeOfNetHeader + 9, tag, 4);
|
||||
|
||||
memcpy(bytes + 13 + sizeOfNetHeader, m_data, sizeof(T));
|
||||
|
||||
size = header.Size;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
uint8_t *SerializeData(uint32_t &size);
|
||||
void Deserialize(uint8_t *data, uint32_t size);
|
||||
|
||||
template<typename T>
|
||||
T *GetData() const
|
||||
{
|
||||
return (T*)m_data;
|
||||
}
|
||||
};
|
||||
}
|
||||
18
include/HLAPI/NewConnectionEvent.hpp
Normal file
18
include/HLAPI/NewConnectionEvent.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class NewConnectionEvent
|
||||
{
|
||||
public:
|
||||
inline NewConnectionEvent(uint32_t id, void *data)
|
||||
: m_id(id)
|
||||
, m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
void *m_data;
|
||||
};
|
||||
}
|
||||
26
include/HLAPI/Server.hpp
Normal file
26
include/HLAPI/Server.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <Net.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpServer;
|
||||
|
||||
class MessageQueue;
|
||||
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(uint32_t max_connections = 20, uint16_t port = DEFAULT_SERVER_PORT);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::net::TcpServer> m_tcpServer;
|
||||
|
||||
std::shared_ptr<MessageQueue> m_queue;
|
||||
};
|
||||
}
|
||||
40
include/HLAPI/TcpConnection.hpp
Normal file
40
include/HLAPI/TcpConnection.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "TcpClient.hpp"
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpConnection
|
||||
{
|
||||
public:
|
||||
friend class TcpConnectionHandler;
|
||||
|
||||
TcpConnection(TcpClient *client);
|
||||
|
||||
std::shared_ptr<TcpClient> GetClient();
|
||||
uint32_t GetID();
|
||||
void SetID(uint32_t id);
|
||||
|
||||
template<typename T>
|
||||
void SendMessage(DistributionMode mode, uint32_t destinationId, uint32_t tag, void *data)
|
||||
{
|
||||
NetworkMessage msg(m_id, mode, destinationId, tag, data, sizeof(T));
|
||||
}
|
||||
|
||||
void ReceiveData();
|
||||
|
||||
std::function<void(uint32_t, DistributionMode, uint32_t, uint32_t, void*)> DataReceivedEvent;
|
||||
std::function<void(uint32_t, std::string, int32_t)> DisconnectedEvent;
|
||||
std::function<void(uint32_t, void*)> NewConnectionEvent;
|
||||
|
||||
private:
|
||||
bool sendMessage(NetworkMessage &msg);
|
||||
|
||||
std::shared_ptr<TcpClient> m_client;
|
||||
uint32_t m_id;
|
||||
};
|
||||
}
|
||||
63
include/HLAPI/TcpConnectionHandler.hpp
Normal file
63
include/HLAPI/TcpConnectionHandler.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <queue>
|
||||
|
||||
#include <TcpListener.hpp>
|
||||
#include <TcpConnection.hpp>
|
||||
|
||||
//#include <BaseLibrary/SpinMutex.hpp>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class MessageQueue;
|
||||
class TcpConnection;
|
||||
class Server;
|
||||
|
||||
namespace sockets
|
||||
{
|
||||
class TcpListener;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpConnectionHandler
|
||||
{
|
||||
friend class std::net::Server;
|
||||
|
||||
public:
|
||||
TcpConnectionHandler(std::shared_ptr<TcpListener> listener_ptr);
|
||||
~TcpConnectionHandler();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void AddClient(std::shared_ptr<TcpConnection> &c);
|
||||
void SetMaxConnections(uint32_t max_connections);
|
||||
|
||||
uint32_t GetAvailableID();
|
||||
|
||||
private:
|
||||
void HandleReceiveMsgAndConns();
|
||||
void HandleSend();
|
||||
|
||||
void HandleReceiveMsgAndConnsThreaded();
|
||||
void HandleSendThreaded();
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<TcpConnection>> m_list;
|
||||
std::mutex m_listMutex;
|
||||
|
||||
uint32_t m_maxConnections;
|
||||
|
||||
std::thread m_receiveThread;
|
||||
std::thread m_sendThread;
|
||||
|
||||
std::atomic_bool m_run;
|
||||
|
||||
std::shared_ptr<MessageQueue> m_queue;
|
||||
|
||||
std::shared_ptr<TcpListener> m_listenerPtr;
|
||||
};
|
||||
}
|
||||
31
include/HLAPI/TcpServer.hpp
Normal file
31
include/HLAPI/TcpServer.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "TcpListener.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class Server;
|
||||
class TcpConnectionHandler;
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
friend class std::net::Server;
|
||||
|
||||
public:
|
||||
TcpServer(uint32_t max_connections, uint16_t port = DEFAULT_SERVER_PORT);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<TcpListener> listener;
|
||||
uint32_t m_maxConnections;
|
||||
uint16_t m_port;
|
||||
|
||||
std::atomic_bool m_run;
|
||||
|
||||
std::shared_ptr<std::net::TcpConnectionHandler> m_connectionHandler;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user