+
+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<Target> targets;
+
+public:
+ template<typename P>
+ void add_receiver(unsigned, PacketReceiver<P> &);
+
+ void receive(unsigned, const Variant &) override;
+};
+
+
+template<typename P>
+void DynamicDispatcher::add_receiver(unsigned packet_id, PacketReceiver<P> &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<PacketReceiver<P> &>(receiver).receive(packet.value<P>());
+ };
+
+ targets.emplace(i, packet_id, r, +dispatch);
+}
+