X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnet%2Freceiver.h;h=a0a9f2913d0ed0e48fb6a47aa5793f04aa76ac99;hb=HEAD;hp=19e69e0d4c5926ceaa9c23ec518731fdcc82fcf3;hpb=debe1004676d5431e571d9c4361072661dcc88c4;p=libs%2Fnet.git diff --git a/source/net/receiver.h b/source/net/receiver.h index 19e69e0..a0a9f29 100644 --- a/source/net/receiver.h +++ b/source/net/receiver.h @@ -1,26 +1,81 @@ #ifndef MSP_NET_RECEIVER_H_ #define MSP_NET_RECEIVER_H_ +#include +#include +#include +#include +#include "mspnet_api.h" + namespace Msp { namespace Net { -class ReceiverBase +class MSPNET_API ReceiverBase { protected: - ReceiverBase() { } + ReceiverBase() = default; public: - virtual ~ReceiverBase() { } + virtual ~ReceiverBase() = default; }; + template class PacketReceiver: public virtual ReceiverBase { protected: - PacketReceiver() { } + PacketReceiver() = default; public: virtual void receive(const P &) = 0; }; + +class MSPNET_API DynamicReceiver: public ReceiverBase +{ +protected: + DynamicReceiver() = default; +public: + virtual void receive(unsigned, const Variant &) = 0; +}; + + +class MSPNET_API DynamicDispatcher: public DynamicReceiver +{ +private: + using DispatchFunc = void(ReceiverBase &, const Variant &); + + struct Target + { + unsigned packet_id; + ReceiverBase *receiver; + DispatchFunc *func; + + Target(unsigned i, ReceiverBase &r, DispatchFunc *f): packet_id(i), receiver(&r), func(f) { } + }; + + std::vector targets; + +public: + template + void add_receiver(unsigned, PacketReceiver

&); + + void receive(unsigned, const Variant &) override; +}; + + +template +void DynamicDispatcher::add_receiver(unsigned packet_id, PacketReceiver

&r) +{ + auto i = lower_bound_member(targets, packet_id, &Target::packet_id); + if(i!=targets.end() && i->packet_id==packet_id) + throw key_error(packet_id); + + auto dispatch = [](ReceiverBase &receiver, const Variant &packet){ + dynamic_cast &>(receiver).receive(packet.value

()); + }; + + targets.emplace(i, packet_id, r, +dispatch); +} + } // namespace Net } // namespace Msp