X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fnet%2Freceiver.h;h=a0a9f2913d0ed0e48fb6a47aa5793f04aa76ac99;hb=HEAD;hp=de7209e4fc765d9d8d6d1d558aebecb6d075309f;hpb=d11d422d06ca0277dff4860a0bf71b1844c94b8a;p=libs%2Fnet.git diff --git a/source/net/receiver.h b/source/net/receiver.h index de7209e..a0a9f29 100644 --- a/source/net/receiver.h +++ b/source/net/receiver.h @@ -1,10 +1,16 @@ #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() = default; @@ -12,6 +18,7 @@ public: virtual ~ReceiverBase() = default; }; + template class PacketReceiver: public virtual ReceiverBase { @@ -21,6 +28,54 @@ 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