Handle signals properly.

This commit is contained in:
Tristan Hume 2015-05-01 20:53:39 -04:00
parent 1457b249b7
commit 602b3958fd
3 changed files with 24 additions and 13 deletions

7
Rakefile Normal file
View file

@ -0,0 +1,7 @@
task :testCall do
sh "dbus-send --type=method_call --print-reply --dest=ca.thume.ddbus.test /root ca.thume.test.test int32:5"
end
task :testSignal do
sh "dbus-send --dest=ca.thume.ddbus.test /signaler ca.thume.test.signal int32:9"
end

View file

@ -24,6 +24,10 @@ void testServe(Connection conn) {
writeln("Called with ", par); writeln("Called with ", par);
return par; return par;
}); });
patt = MessagePattern("/signaler","ca.thume.test","signal",true);
router.setHandler!(void,int)(patt,(int par) {
writeln("Signalled with ", par);
});
registerRouter(conn, router); registerRouter(conn, router);
writeln("Getting name..."); writeln("Getting name...");
bool gotem = requestName(conn, "ca.thume.ddbus.test"); bool gotem = requestName(conn, "ca.thume.ddbus.test");

View file

@ -10,38 +10,34 @@ struct MessagePattern {
string path; string path;
string iface; string iface;
string method; string method;
string sender; bool signal;
this(Message msg) { this(Message msg) {
path = msg.path(); path = msg.path();
iface = msg.iface(); iface = msg.iface();
method = msg.member(); method = msg.member();
if(msg.type()==MessageType.Signal) { signal = (msg.type() == MessageType.Signal);
sender = msg.sender();
} else {
sender = null;
}
} }
this(string path, string iface, string method, string sender = null) { this(string path, string iface, string method, bool signal = false) {
this.path = path; this.path = path;
this.iface = iface; this.iface = iface;
this.method = method; this.method = method;
this.sender = sender; this.signal = signal;
} }
size_t toHash() const @safe nothrow { size_t toHash() const @safe nothrow {
size_t hash = 0; size_t hash = 0;
auto stringHash = &(typeid(path).getHash); auto stringHash = &(typeid(path).getHash);
hash += stringHash(&sender);
hash += stringHash(&path); hash += stringHash(&path);
hash += stringHash(&iface); hash += stringHash(&iface);
hash += stringHash(&method); hash += stringHash(&method);
hash += (signal?1:0);
return hash; return hash;
} }
bool opEquals(ref const this s) const @safe pure nothrow { bool opEquals(ref const this s) const @safe pure nothrow {
return (path == s.path) && (iface == s.iface) && (method == s.method) && (sender == s.sender); return (path == s.path) && (iface == s.iface) && (method == s.method) && (signal == s.signal);
} }
} }
@ -54,6 +50,7 @@ class MessageRouter {
if(type != MessageType.Call && type != MessageType.Signal) if(type != MessageType.Call && type != MessageType.Signal)
return false; return false;
auto pattern = MessagePattern(msg); auto pattern = MessagePattern(msg);
// import std.stdio; debug writeln("Handling ", pattern);
HandlerFunc* handler = (pattern in callTable); HandlerFunc* handler = (pattern in callTable);
if(handler is null) return false; if(handler is null) return false;
(*handler)(msg,conn); (*handler)(msg,conn);
@ -63,12 +60,15 @@ class MessageRouter {
void setHandler(Ret, Args...)(MessagePattern patt, Ret delegate(Args) handler) { void setHandler(Ret, Args...)(MessagePattern patt, Ret delegate(Args) handler) {
void handlerWrapper(Message call, Connection conn) { void handlerWrapper(Message call, Connection conn) {
Tuple!Args args = call.readTuple!(Tuple!Args)(); Tuple!Args args = call.readTuple!(Tuple!Args)();
Ret ret = handler(args.expand);
auto retMsg = call.createReturn(); auto retMsg = call.createReturn();
static if(!is(Ret == void)) { static if(!is(Ret == void)) {
Ret ret = handler(args.expand);
retMsg.build(ret); retMsg.build(ret);
} else {
handler(args.expand);
} }
conn.send(retMsg); if(!patt.signal)
conn.send(retMsg);
} }
callTable[patt] = &handlerWrapper; callTable[patt] = &handlerWrapper;
} }
@ -103,6 +103,6 @@ unittest {
auto msg = Message("org.example.test", "/test","org.example.testing","testMethod"); auto msg = Message("org.example.test", "/test","org.example.testing","testMethod");
auto patt= new MessagePattern(msg); auto patt= new MessagePattern(msg);
patt.assertEqual(patt); patt.assertEqual(patt);
patt.sender.assertNull(); patt.signal.assertFalse();
patt.path.assertEqual("/test"); patt.path.assertEqual("/test");
} }