On Fri, Mar 28, 2008 at 1:03 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
#include <boost/signal.hpp>
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...
#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>
enum PacketID {
struct Packet {};
struct WalkPacket : Packet {};
PID_WALKPACKET
};
template<class T>
struct GetPacketID;
template<>
struct GetPacketID<WalkPacket> : boost::mpl::integral_c<PacketID,
PID_WALKPACKET> {};
StaticCaster(boost::shared_ptr<boost::signal<void(T const&)> >
template<class T>
struct StaticCaster {
const& signal) : signal(signal) {}
boost::shared_ptr<boost::signal<void(T const&)> > signal;
void operator()(Packet const& packet) const {class SignalHolder {
(*signal)(static_cast<T const&>(packet));
}
};
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&)>
>(iter->second.first)->connect(f);
};
void operator()(PacketID id, const Packet& packet) {
dispatcher[id].second(packet);
}
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