#pragma once #include "../../core/net/Context.hpp" #include namespace net::server { enum queue: uint8_t { GLOBAL = 0, ENTITY, CHUNK, count }; class Peer final: public Connection { public: Peer(picoquic_cnx_t *cnx): Connection(cnx, false, queue::count) { } ~Peer() { assert(ctx == nullptr); } template constexpr C *getCtx() { assert(ctx != nullptr); return (C *)ctx; } void *ctx = nullptr; }; class Server final: Context { public: Server(const exposure& ct, std::function(Peer*)> onConnect, std::function onDisconnect, std::function 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 void iterPeers(C call) { for(auto& peer: peers) { call(&peer); } } private: std::forward_list peers; std::function(Peer *)> onConnect; std::function onDisconnect; std::function onPacket; uint32_t max_connections; }; }