Add a simple method of routing to an object.
This commit is contained in:
parent
8771b8b2b1
commit
d60a78cde8
|
@ -128,7 +128,7 @@ class MessageRouter {
|
|||
formattedWrite(app,introspectHeader,path);
|
||||
foreach(iface; ifaces) {
|
||||
formattedWrite(app,`<interface name="%s">`,iface.front.iface);
|
||||
foreach(methodPatt; iface) {
|
||||
foreach(methodPatt; iface.array()) {
|
||||
formattedWrite(app,`<method name="%s">`,methodPatt.method);
|
||||
auto handler = callTable[methodPatt];
|
||||
foreach(arg; handler.argSig) {
|
||||
|
@ -149,7 +149,7 @@ class MessageRouter {
|
|||
auto children = callTable.byKey().filter!(a => (a.path.startsWith(childPath)) && !a.signal)()
|
||||
.map!((s) => s.path.chompPrefix(childPath))
|
||||
.map!((s) => s.splitter('/').front)
|
||||
.uniq();
|
||||
.array().sort().uniq();
|
||||
foreach(child; children) {
|
||||
formattedWrite(app,`<node name="%s"/>`,child);
|
||||
}
|
||||
|
@ -199,9 +199,12 @@ unittest{
|
|||
router.setHandler!(void,int,string)(patt,(int p, string p2) {});
|
||||
patt = MessagePattern("/root/wat","ca.thume.tester","lolwut");
|
||||
router.setHandler!(int,int)(patt,(int p) {return 6;});
|
||||
patt = MessagePattern("/troll","ca.thume.tester","wow");
|
||||
router.setHandler!(void)(patt,{return;});
|
||||
|
||||
// TODO: these tests rely on nondeterministic hash map ordering
|
||||
static string introspectResult = `<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node name="/root"><interface name="ca.thume.test"><method name="test"><arg type="i" direction="in"/><arg type="i" direction="out"/></method></interface><interface name="ca.thume.tester"><method name="lolwut"><arg type="i" direction="in"/><arg type="s" direction="in"/></method></interface><node name="wat"/></node>`;
|
||||
router.introspectXML("/root").assertEqual(introspectResult);
|
||||
router.introspectXML("/").assertEndsWith(`<node name="/"><node name="root"/></node>`);
|
||||
router.introspectXML("/").assertEndsWith(`<node name="/"><node name="root"/><node name="troll"/></node>`);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ module ddbus.simple;
|
|||
import ddbus.thin;
|
||||
import ddbus.util;
|
||||
import ddbus.c_lib;
|
||||
import ddbus.router;
|
||||
import std.string;
|
||||
import std.traits;
|
||||
|
||||
class PathIface {
|
||||
this(Connection conn, string dest, string path, string iface) {
|
||||
|
@ -41,3 +43,45 @@ unittest {
|
|||
names.assertEqual("org.freedesktop.DBus");
|
||||
obj.call!string("GetNameOwner","org.freedesktop.DBus").assertEqual("org.freedesktop.DBus");
|
||||
}
|
||||
|
||||
/**
|
||||
Registers all *possible* methods of an object in a router.
|
||||
It will not register methods that use types that ddbus can't handle.
|
||||
|
||||
The implementation is rather hacky and uses the compiles trait to check for things
|
||||
working so if some methods randomly don't seem to be added, you should probably use
|
||||
setHandler on the router directly. It is also not efficient and creates a closure for every method.
|
||||
|
||||
TODO: replace this with something that generates a wrapper class who's methods take and return messages
|
||||
and basically do what MessageRouter.setHandler does but avoiding duplication. Then this DBusWrapper!Class
|
||||
could be instantiated with any object efficiently and placed in the router table with minimal duplication.
|
||||
*/
|
||||
void registerMethods(T : Object)(MessageRouter router, string path, string iface, T obj) {
|
||||
MessagePattern patt = MessagePattern(path,iface,"",false);
|
||||
foreach(member; __traits(allMembers, T)) {
|
||||
static if (__traits(compiles, __traits(getOverloads, obj, member))
|
||||
&& __traits(getOverloads, obj, member).length > 0
|
||||
&& __traits(compiles, router.setHandler(patt, &__traits(getOverloads,obj,member)[0]))) {
|
||||
patt.method = member;
|
||||
router.setHandler(patt, &__traits(getOverloads,obj,member)[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unittest {
|
||||
import dunit.toolkit;
|
||||
class Tester {
|
||||
int lol(int x, string s) {return 5;}
|
||||
void wat() {}
|
||||
}
|
||||
auto o = new Tester;
|
||||
auto router = new MessageRouter;
|
||||
registerMethods(router, "/","ca.thume.test",o);
|
||||
MessagePattern patt = MessagePattern("/","ca.thume.test","wat");
|
||||
router.callTable.assertHasKey(patt);
|
||||
patt.method = "lol";
|
||||
router.callTable.assertHasKey(patt);
|
||||
auto res = router.callTable[patt];
|
||||
res.argSig.assertEqual(["i","s"]);
|
||||
res.retSig.assertEqual(["i"]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue