Some work on update impl
This commit is contained in:
parent
640102c091
commit
0bd51418a2
2 changed files with 111 additions and 5 deletions
|
@ -2,15 +2,47 @@
|
||||||
#define UDPC_DEFINES_HPP
|
#define UDPC_DEFINES_HPP
|
||||||
|
|
||||||
#define UDPC_CONTEXT_IDENTIFIER 0x902F4DB3
|
#define UDPC_CONTEXT_IDENTIFIER 0x902F4DB3
|
||||||
|
#define UDPC_TIMEOUT_SECONDS 10.0f
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <deque>
|
||||||
|
#include <chrono>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "UDPConnection.h"
|
#include "UDPConnection.h"
|
||||||
|
#include "TSQueue.hpp"
|
||||||
|
|
||||||
namespace UDPC {
|
namespace UDPC {
|
||||||
|
|
||||||
|
struct ConnectionData {
|
||||||
|
/*
|
||||||
|
* 0 - trigger send
|
||||||
|
* 1 - is good mode
|
||||||
|
* 2 - is good rtt
|
||||||
|
* 3 - initiating connection to server
|
||||||
|
* 4 - is id set
|
||||||
|
*/
|
||||||
|
std::bitset<32> flags;
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t lseq;
|
||||||
|
uint32_t rseq;
|
||||||
|
uint32_t ack;
|
||||||
|
float timer;
|
||||||
|
float toggleT;
|
||||||
|
float toggleTimer;
|
||||||
|
float toggledTimer;
|
||||||
|
uint32_t addr; // in network order
|
||||||
|
uint16_t port;
|
||||||
|
std::deque<PacketInfo> sentPkts;
|
||||||
|
TSQueue<PacketInfo> sendPkts;
|
||||||
|
TSQueue<PacketInfo> priorityPkts;
|
||||||
|
std::chrono::steady_clock::time_point received;
|
||||||
|
std::chrono::steady_clock::time_point sent;
|
||||||
|
float rtt;
|
||||||
|
}; // struct ConnectionData
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
Context(bool isThreaded);
|
Context(bool isThreaded);
|
||||||
|
|
||||||
|
@ -23,6 +55,12 @@ struct Context {
|
||||||
std::atomic_uint32_t protocolID;
|
std::atomic_uint32_t protocolID;
|
||||||
std::atomic_uint_fast8_t loggingType;
|
std::atomic_uint_fast8_t loggingType;
|
||||||
char atostrBuf[16];
|
char atostrBuf[16];
|
||||||
|
|
||||||
|
int socketHandle;
|
||||||
|
struct sockaddr_in socketInfo;
|
||||||
|
|
||||||
|
std::chrono::steady_clock::time_point lastUpdated;
|
||||||
|
std::unordered_map<uint32_t, ConnectionData> conMap;
|
||||||
}; // struct Context
|
}; // struct Context
|
||||||
|
|
||||||
Context* verifyContext(void *ctx);
|
Context* verifyContext(void *ctx);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "UDPC_Defines.hpp"
|
#include "UDPC_Defines.hpp"
|
||||||
#include "UDPConnection.h"
|
#include "UDPConnection.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
UDPC::Context::Context(bool isThreaded)
|
UDPC::Context::Context(bool isThreaded)
|
||||||
: _contextIdentifier(UDPC_CONTEXT_IDENTIFIER), flags(),
|
: _contextIdentifier(UDPC_CONTEXT_IDENTIFIER), flags(),
|
||||||
|
@ -48,12 +50,54 @@ bool UDPC::isBigEndian() {
|
||||||
void *UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
|
void *UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
|
||||||
UDPC::Context *ctx = new UDPC::Context(false);
|
UDPC::Context *ctx = new UDPC::Context(false);
|
||||||
|
|
||||||
|
// create socket
|
||||||
|
ctx->socketHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if(ctx->socketHandle <= 0) {
|
||||||
|
// TODO maybe different way of handling init fail
|
||||||
|
delete ctx;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind socket
|
||||||
|
ctx->socketInfo.sin_family = AF_INET;
|
||||||
|
ctx->socketInfo.sin_addr.s_addr =
|
||||||
|
(listenAddr == 0 ? INADDR_ANY : listenAddr);
|
||||||
|
ctx->socketInfo.sin_port = htons(listenPort);
|
||||||
|
if(bind(ctx->socketHandle, (const struct sockaddr *)&ctx->socketInfo,
|
||||||
|
sizeof(struct sockaddr_in)) < 0) {
|
||||||
|
// TODO maybe different way of handling init fail
|
||||||
|
CleanupSocket(ctx->socketHandle);
|
||||||
|
delete ctx;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set non-blocking on socket
|
||||||
|
#if UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX
|
||||||
|
int nonblocking = 1;
|
||||||
|
if(fcntl(ctx->socketHandle, F_SETFL, O_NONBLOCK, nonblocking) == -1) {
|
||||||
|
#elif UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
|
||||||
|
DWORD nonblocking = 1;
|
||||||
|
if(ioctlsocket(ctx->socketHandle, FIONBIO, &nonblocking) != 0) {
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
// TODO maybe different way of handling init fail
|
||||||
|
CleanupSocket(ctx->socketHandle);
|
||||||
|
delete ctx;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr,
|
void *UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr,
|
||||||
int isClient) {
|
int isClient) {
|
||||||
UDPC::Context *ctx = new UDPC::Context(true);
|
UDPC::Context *ctx =
|
||||||
|
(UDPC::Context *)UDPC_init(listenPort, listenAddr, isClient);
|
||||||
|
if(!ctx) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ctx->flags.set(0);
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
@ -67,12 +111,36 @@ void UDPC_destroy(void *ctx) {
|
||||||
|
|
||||||
void UDPC_update(void *ctx) {
|
void UDPC_update(void *ctx) {
|
||||||
UDPC::Context *c = UDPC::verifyContext(ctx);
|
UDPC::Context *c = UDPC::verifyContext(ctx);
|
||||||
if(!c) {
|
if(!c || c->flags.test(0)) {
|
||||||
|
// invalid or is threaded, update should not be called
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(c->flags.test(0)) {
|
|
||||||
// is threaded, update should not be called
|
const auto now = std::chrono::steady_clock::now();
|
||||||
return;
|
const auto dt = now - c->lastUpdated;
|
||||||
|
const float dt_fs = (float)dt.count() * (float)decltype(dt)::period::num /
|
||||||
|
(float)decltype(dt)::period::den;
|
||||||
|
|
||||||
|
std::chrono::steady_clock::duration temp_dt;
|
||||||
|
float temp_dt_fs;
|
||||||
|
std::vector<uint32_t> removed;
|
||||||
|
for(auto iter = c->conMap.begin(); iter != c->conMap.end(); ++iter) {
|
||||||
|
temp_dt = now - iter->second.received;
|
||||||
|
temp_dt_fs = (float)temp_dt.count() *
|
||||||
|
(float)decltype(temp_dt)::period::num /
|
||||||
|
(float)decltype(temp_dt)::period::den;
|
||||||
|
if(temp_dt_fs >= UDPC_TIMEOUT_SECONDS) {
|
||||||
|
removed.push_back(iter->first);
|
||||||
|
// TODO log timed out connection
|
||||||
|
}
|
||||||
|
|
||||||
|
// check good/bad mode
|
||||||
|
iter->second.toggleTimer += temp_dt_fs;
|
||||||
|
iter->second.toggledTimer += temp_dt_fs;
|
||||||
|
if(iter->second.flags.test(1) && !iter->second.flags.test(2)) {
|
||||||
|
// good mode, bad rtt
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO impl
|
// TODO impl
|
||||||
|
|
Loading…
Reference in a new issue