X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnet%2Fcommunicator.h;h=eb9893d861a2ca8eaa3679aeedcddcd6fde24ea4;hb=HEAD;hp=b98f488ff3f63ef64016c6a22d23e4aaf188a93c;hpb=afd2a8365ccc49b1b69ca034dd4abae37ee83eed;p=libs%2Fnet.git diff --git a/source/net/communicator.h b/source/net/communicator.h index b98f488..eb9893d 100644 --- a/source/net/communicator.h +++ b/source/net/communicator.h @@ -4,6 +4,7 @@ #include #include #include +#include "mspnet_api.h" #include "protocol.h" namespace Msp { @@ -11,30 +12,45 @@ namespace Net { class StreamSocket; -class sequence_error: public invalid_state +class MSPNET_API sequence_error: public invalid_state { public: sequence_error(const std::string &w): invalid_state(w) { } }; -class incompatible_protocol: public std::runtime_error +class MSPNET_API incompatible_protocol: public std::runtime_error { public: incompatible_protocol(const std::string &w): std::runtime_error(w) { } }; -class Communicator: public NonCopyable +class MSPNET_API Communicator: public NonCopyable { public: - sigc::signal signal_handshake_done; + sigc::signal signal_protocol_ready; sigc::signal signal_error; private: + struct ActiveProtocol + { + std::uint64_t hash = 0; + std::uint16_t base = 0; + std::uint16_t last = 0; + bool accepted = false; + bool ready = false; + const Protocol *protocol = nullptr; + ReceiverBase *receiver = nullptr; + + ActiveProtocol(std::uint16_t, const Protocol &, ReceiverBase &); + ActiveProtocol(std::uint16_t, std::uint64_t); + }; + + struct Handshake; + StreamSocket &socket; - const Protocol &protocol; - ReceiverBase &receiver; - int handshake_status = 0; + std::vector protocols; + Handshake *handshake = nullptr; std::size_t buf_size = 65536; char *in_buf = nullptr; char *in_begin = nullptr; @@ -43,11 +59,12 @@ private: bool good = true; public: + Communicator(StreamSocket &); Communicator(StreamSocket &, const Protocol &, ReceiverBase &); ~Communicator(); - void initiate_handshake(); - bool is_handshake_done() const { return handshake_status==2; } + void add_protocol(const Protocol &, ReceiverBase &); + bool is_protocol_ready(const Protocol &) const; template void send(const P &); @@ -55,15 +72,23 @@ public: private: void send_data(std::size_t); + void connect_finished(const std::exception *); void data_available(); - bool receive_packet(const Protocol &, ReceiverBase &); - void send_handshake(); + bool receive_packet(); + + void prepare_protocol(const ActiveProtocol &); + void accept_protocol(ActiveProtocol &); }; template void Communicator::send(const P &pkt) { - send_data(protocol.serialize(pkt, out_buf, buf_size)); + auto i = find_if(protocols, [](const ActiveProtocol &p){ return p.protocol && p.protocol->has_packet

(); }); + if(i==protocols.end()) + throw key_error(typeid(P).name()); + else if(!i->ready) + throw sequence_error("protocol not ready"); + send_data(i->protocol->serialize(pkt, out_buf, buf_size, i->base)); } } // namespace Net