From 116144085c5fc68009ac90d77efd61507aa7585c Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Thu, 21 Feb 2013 22:40:30 +0100 Subject: digital/ucoolib/ucoolib/arch/host/mex: simplify handlers thanks to TR1 TR1 (and C++11, but this must compile on debian squeeze) defines function objects which can contain any callable which respects the prototype. This greatly simplify handler code. Also, get rid of get_instance and give Node as handler parameter instead. --- digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh | 70 ++++++++-------------- .../ucoolib/ucoolib/arch/host/mex/mex_node.host.cc | 27 +++------ .../ucoolib/ucoolib/arch/host/mex/test/test_mex.cc | 12 ++-- 3 files changed, 38 insertions(+), 71 deletions(-) (limited to 'digital') diff --git a/digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh b/digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh index 26fd5a29..11d038d4 100644 --- a/digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh +++ b/digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh @@ -30,53 +30,20 @@ #include #include #include +#include namespace ucoo { namespace mex { -class Node; - -/// Abstract message reception handler. -class Handler -{ - public: - /// Handle a received message or request. - virtual void handle (Msg &msg) = 0; -}; - -/// Helper class for member function reception handler. -template -class HandlerMemfun : public Handler -{ - public: - HandlerMemfun (T &obj, void (T::*f) (Msg &)) - : obj_ (obj), f_ (f) { } - void handle (Msg &msg) { (obj_.*f_) (msg); } - private: - T &obj_; - void (T::*f_) (Msg &); -}; - -/// Helper class for static function reception handler. -class HandlerPtrfun : public Handler -{ - public: - HandlerPtrfun (void (*f) (Msg &)) : f_ (f) { } - void handle (Msg &msg) { f_ (msg); } - private: - void (*f_) (Msg &); -}; - /// Mex node, singleton. class Node { + public: + /// Message handler type. + typedef std::tr1::function Handler; public: /// Connect to mex hub. Node (); - /// Disconnect. - ~Node (); - /// Get single instance, may return NULL if none constructed. - static Node *instance () { return instance_; } /// Wait forever. void wait (); /// Wait until date is reached. @@ -91,8 +58,25 @@ class Node void response (Msg &msg); /// Reserve a message type. mtype_t reserve (const std::string &name); - /// Register an handler for a message type. - void handler_register (mtype_t mtype, Handler &handler); + /// Register a handler for a message type. + void handler_register (mtype_t mtype, Handler handler); + /// Register a handler for a message type, member function version. + template + void handler_register (mtype_t mtype, T &obj, + void (T::*handler) (Node &, Msg &)) + { + using namespace std::tr1::placeholders; + handler_register (mtype, std::tr1::bind (handler, &obj, _1, _2)); + } + /// Register a handler for a message type, member function version, + /// without Node parameter. + template + void handler_register (mtype_t mtype, T &obj, + void (T::*handler) (Msg &)) + { + using namespace std::tr1::placeholders; + handler_register (mtype, std::tr1::bind (handler, &obj, _2)); + } private: /// Receive one message. std::auto_ptr recv (); @@ -103,8 +87,6 @@ class Node /// Handle an incomming REQ message. void handle_req (Msg &msg); private: - /// Pointer to single instance. - static Node *instance_; /// Connection to hub. Socket socket_; /// Current date. @@ -112,10 +94,8 @@ class Node /// When handling a request, this is the request identifier, else -1. int req_; /// Registered handlers. - typedef std::map handlers_type; - handlers_type handlers_; - /// Handlers objects. - HandlerMemfun handler_date, handler_req; + typedef std::map Handlers; + Handlers handlers_; }; } // namespace mex diff --git a/digital/ucoolib/ucoolib/arch/host/mex/mex_node.host.cc b/digital/ucoolib/ucoolib/arch/host/mex/mex_node.host.cc index d1a4c703..eb62ef9d 100644 --- a/digital/ucoolib/ucoolib/arch/host/mex/mex_node.host.cc +++ b/digital/ucoolib/ucoolib/arch/host/mex/mex_node.host.cc @@ -28,21 +28,15 @@ namespace ucoo { namespace mex { -Node *Node::instance_; - Node::Node () : date_ (0), - req_ (-1), - handler_date (*this, &Node::handle_date), - handler_req (*this, &Node::handle_req) + req_ (-1) { - assert (!instance_); - instance_ = this; // Connect. socket_.connect (); // Setup default handlers. - handler_register (MTYPE_DATE, handler_date); - handler_register (MTYPE_REQ, handler_req); + handler_register (MTYPE_DATE, *this, &Node::handle_date); + handler_register (MTYPE_REQ, *this, &Node::handle_req); // Synchronise with the hub. bool sync = false; while (!sync) @@ -54,11 +48,6 @@ Node::Node () } } -Node::~Node () -{ - instance_ = 0; -} - void Node::wait () { @@ -145,10 +134,10 @@ Node::reserve (const std::string &name) } void -Node::handler_register (mtype_t mtype, Handler &handler) +Node::handler_register (mtype_t mtype, Handler handler) { - std::pair r = - handlers_.insert (handlers_type::value_type (mtype, &handler)); + std::pair r = + handlers_.insert (Handlers::value_type (mtype, handler)); assert (r.second); } @@ -161,9 +150,9 @@ Node::recv () void Node::dispatch (Msg &msg) { - handlers_type::const_iterator it = handlers_.find (msg.mtype ()); + Handlers::const_iterator it = handlers_.find (msg.mtype ()); if (it != handlers_.end ()) - it->second->handle (msg); + it->second (*this, msg); } void diff --git a/digital/ucoolib/ucoolib/arch/host/mex/test/test_mex.cc b/digital/ucoolib/ucoolib/arch/host/mex/test/test_mex.cc index f260203b..9628ca16 100644 --- a/digital/ucoolib/ucoolib/arch/host/mex/test/test_mex.cc +++ b/digital/ucoolib/ucoolib/arch/host/mex/test/test_mex.cc @@ -183,7 +183,7 @@ test_node_1 () } void -test_node_2_handle_hello (Msg &msg) +test_node_2_handle_hello (Node &, Msg &msg) { int pass; msg.pop ("l") >> pass; @@ -192,14 +192,14 @@ test_node_2_handle_hello (Msg &msg) } void -test_node_2_handle_world (Msg &msg) +test_node_2_handle_world (Node &node, Msg &msg) { int a, b; msg.pop ("bh") >> a >> b; printf ("world\n"); Msg resp (msg.mtype ()); resp.push ("l") << a + b; - Node::instance ()->response (resp); + node.response (resp); } void @@ -209,10 +209,8 @@ test_node_2 () mtype_t hello_mtype, world_mtype; hello_mtype = node.reserve ("hello"); world_mtype = node.reserve ("world"); - HandlerPtrfun hello_handler (test_node_2_handle_hello); - HandlerPtrfun world_handler (test_node_2_handle_world); - node.handler_register (hello_mtype, hello_handler); - node.handler_register (world_mtype, world_handler); + node.handler_register (hello_mtype, test_node_2_handle_hello); + node.handler_register (world_mtype, test_node_2_handle_world); node.wait (); } -- cgit v1.2.3