
AMDG Robert Dailey wrote:
Subscription doesn't seem as simple as you proposed. I looked into possible designs for subscribing to the signals and nothing is working out. There's no way to generate a second map to provide slot connections, since the signal object is actually owned by the first map, and thus the two cannot share them. Secondly, the slots (given the design above) each have a different signature for each packet, which further complicates things.
Any suggestions? I'm having trouble thinking outside the box...
(iter->second.first)->connect(f); }; void operator()(PacketID id, const Packet& packet) { dispatcher[id].second(packet); }
#include <boost/signal.hpp> #include <boost/function.hpp> #include <boost/unordered_map.hpp> #include <boost/shared_ptr.hpp> #include <boost/mpl/integral_c.hpp> #include <vector> #include <utility> #include <iostream> struct Packet {}; struct WalkPacket : Packet {}; enum PacketID { PID_WALKPACKET }; template<class T> struct GetPacketID; template<> struct GetPacketID<WalkPacket> : boost::mpl::integral_c<PacketID, PID_WALKPACKET> {}; template<class T> struct StaticCaster { StaticCaster(boost::shared_ptr<boost::signal<void(T const&)> > const& signal) : signal(signal) {} boost::shared_ptr<boost::signal<void(T const&)> > signal; void operator()(Packet const& packet) const { (*signal)(static_cast<T const&>(packet)); } }; class SignalHolder { public: template<class T, class F> void register_function(F f) { const PacketID id = GetPacketID<T>::value; dispatcher_t::iterator iter = dispatcher.find(id); if(iter == dispatcher.end()) { boost::shared_ptr<boost::signal<void(T const&)> > signal(new boost::signal<void(T const&)>()); iter = dispatcher.insert(std::make_pair(id, std::make_pair(static_cast<boost::shared_ptr<void> >(signal), StaticCaster<T>(signal)))).first; } boost::static_pointer_cast<boost::signal<void(T const&)> private: typedef boost::unordered_map<PacketID, std::pair<boost::shared_ptr<void>, boost::function<void(Packet const&)>
dispatcher_t; dispatcher_t dispatcher; };
void test(WalkPacket const&) { std::cout << "Got a WalkPacket" << std::endl; } int main() { SignalHolder holder; holder.register_function<WalkPacket>(&test); WalkPacket packet; holder(PID_WALKPACKET, packet); } In Christ, Steven Watanabe