summaryrefslogtreecommitdiffhomepage
path: root/digital/ucoolib/ucoolib
diff options
context:
space:
mode:
authorNicolas Schodet2013-02-21 22:40:30 +0100
committerNicolas Schodet2013-03-01 22:58:03 +0100
commit116144085c5fc68009ac90d77efd61507aa7585c (patch)
tree662feaba57e53c8c6d7fd3ef72e7e33f5f97583c /digital/ucoolib/ucoolib
parentda2c8f50ee5caafd73470ef2e33cf2d42be23c6c (diff)
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.
Diffstat (limited to 'digital/ucoolib/ucoolib')
-rw-r--r--digital/ucoolib/ucoolib/arch/host/mex/mex_node.hh70
-rw-r--r--digital/ucoolib/ucoolib/arch/host/mex/mex_node.host.cc27
-rw-r--r--digital/ucoolib/ucoolib/arch/host/mex/test/test_mex.cc12
3 files changed, 38 insertions, 71 deletions
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 <memory>
#include <map>
#include <string>
+#include <tr1/functional>
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 T>
-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<void (Node &, Msg &)> 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<class T>
+ 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<class T>
+ 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<Msg> 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<mtype_t, Handler *> handlers_type;
- handlers_type handlers_;
- /// Handlers objects.
- HandlerMemfun<Node> handler_date, handler_req;
+ typedef std::map<mtype_t, Handler> 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<handlers_type::iterator, bool> r =
- handlers_.insert (handlers_type::value_type (mtype, &handler));
+ std::pair<Handlers::iterator, bool> 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 ();
}