#include #include "message.h" #ifndef GHOST_LINK_H #define GHOST_LINK_H using namespace std; // WARNING: The Link system relies on bound member functions, a g++ extended feature, // you must compile with -Wno-pmf-conversions. // TODO change to use input and output operators? << >> template <> struct hash { size_t operator()(void* __x) const { return (size_t)__x; } }; class _Link { public: typedef void (*sig_h_t)(void *); void *m; void *data; // this is closure data - can be a void * or an int - TODO nice way to get an int into it? sig_h_t signal_h; _Link(void *data) : data(data) {} }; typedef hash_map links_t; links_t links; template class Link : _Link { public: typedef void (M::*member_t)(); typedef void (*func_t)(M *); O& o; Link(O& object, M* machine, member_t signal, void *data = 0) : o(object), _Link(data) { hash_map::iterator it = links.find(&o); if (it == links.end()) { links[&object] = this; m = machine; signal_h = (sig_h_t)(func_t)(machine->*signal); } else { _Link *peer_link = it->second; if (peer_link == 0) { fatal("already linked"); } else { m = peer_link->m; signal_h = peer_link->signal_h; peer_link->m = machine; peer_link->signal_h = (sig_h_t)(func_t)(machine->*signal); it->second = 0; } } } void signal() { (*signal_h)(m); } }; #endif