1
0
Fork 0
Univerxel/src/server/net/Server.hpp

80 lines
2.1 KiB
C++

#pragma once
#include "../../core/net/Context.hpp"
#include <functional>
namespace net::server {
enum queue: uint8_t {
GLOBAL = 0,
ENTITY,
CHUNK,
EDIT,
count
};
class Peer final: public Connection {
public:
Peer(picoquic_cnx_t *cnx): Connection(cnx, false, queue::count) { }
~Peer() { assert(ctx == nullptr); }
template <typename C>
constexpr C *getCtx() {
assert(ctx != nullptr);
return (C *)ctx;
}
void *ctx = nullptr;
};
class Server final: Context {
public:
Server(const exposure& ct,
std::function<std::optional<uint16_t>(Peer*)> onConnect,
std::function<bool(Peer*, bool, uint16_t)> onDisconnect,
std::function<bool(Peer *, const data::out_view&, PacketFlags)> onPacket);
~Server();
/// Send unreliable data to all peers
void emitBroadcast(const uint8_t *ptr, size_t size);
/// Send reliable data to all peers
void sendBroadcast(const data::out_buffer& buffer, uint8_t queue = 0, size_t queue_size = 0) {
iterPeers([&](Peer* peer){ peer->send(buffer, queue, queue_size); });
}
/// Register peer or return nullptr
Peer *connect(picoquic_cnx_t *);
/// Read-write on sockets and notify callbacks
void pull() { Context::pull(1000, 50, 20); }
int connectionCallback(Peer* client, uint64_t stream_id, uint8_t *bytes, size_t length,
picoquic_call_back_event_t fin_or_event, void *v_stream_ctx);
bool isRunning() const { return true; }
template<typename C>
void iterPeers(C call) {
for(auto& peer: peers) {
call(&peer);
}
}
template<typename P>
bool anyPeer(P predicate) {
for(auto& peer: peers) {
if(predicate(&peer))
return true;
}
return false;
}
private:
std::forward_list<Peer> peers;
std::function<std::optional<uint16_t>(Peer *)> onConnect;
std::function<bool(Peer *, bool, uint16_t)> onDisconnect;
std::function<bool(Peer *, const data::out_view &, PacketFlags)> onPacket;
uint32_t max_connections;
};
}