X-Git-Url: http://git.tdb.fi/?p=libs%2Fnet.git;a=blobdiff_plain;f=source%2Fnet%2Freceiver.h;fp=source%2Fnet%2Freceiver.h;h=a0a9f2913d0ed0e48fb6a47aa5793f04aa76ac99;hp=9af1bb7154af65a226d96836c43fe48d9bc18fa3;hb=b451f834a6b5440fb1064cf96c69eb5447ae86cf;hpb=3f46fef7032d97b0dd82971ffece1062fd6b05b8 diff --git a/source/net/receiver.h b/source/net/receiver.h index 9af1bb7..a0a9f29 100644 --- a/source/net/receiver.h +++ b/source/net/receiver.h @@ -1,6 +1,10 @@ #ifndef MSP_NET_RECEIVER_H_ #define MSP_NET_RECEIVER_H_ +#include +#include +#include +#include #include "mspnet_api.h" namespace Msp { @@ -14,6 +18,7 @@ public: virtual ~ReceiverBase() = default; }; + template class PacketReceiver: public virtual ReceiverBase { @@ -23,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