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);
|
formattedWrite(app,introspectHeader,path);
|
||||||
foreach(iface; ifaces) {
|
foreach(iface; ifaces) {
|
||||||
formattedWrite(app,`<interface name="%s">`,iface.front.iface);
|
formattedWrite(app,`<interface name="%s">`,iface.front.iface);
|
||||||
foreach(methodPatt; iface) {
|
foreach(methodPatt; iface.array()) {
|
||||||
formattedWrite(app,`<method name="%s">`,methodPatt.method);
|
formattedWrite(app,`<method name="%s">`,methodPatt.method);
|
||||||
auto handler = callTable[methodPatt];
|
auto handler = callTable[methodPatt];
|
||||||
foreach(arg; handler.argSig) {
|
foreach(arg; handler.argSig) {
|
||||||
|
@ -149,7 +149,7 @@ class MessageRouter {
|
||||||
auto children = callTable.byKey().filter!(a => (a.path.startsWith(childPath)) && !a.signal)()
|
auto children = callTable.byKey().filter!(a => (a.path.startsWith(childPath)) && !a.signal)()
|
||||||
.map!((s) => s.path.chompPrefix(childPath))
|
.map!((s) => s.path.chompPrefix(childPath))
|
||||||
.map!((s) => s.splitter('/').front)
|
.map!((s) => s.splitter('/').front)
|
||||||
.uniq();
|
.array().sort().uniq();
|
||||||
foreach(child; children) {
|
foreach(child; children) {
|
||||||
formattedWrite(app,`<node name="%s"/>`,child);
|
formattedWrite(app,`<node name="%s"/>`,child);
|
||||||
}
|
}
|
||||||
|
@ -199,9 +199,12 @@ unittest{
|
||||||
router.setHandler!(void,int,string)(patt,(int p, string p2) {});
|
router.setHandler!(void,int,string)(patt,(int p, string p2) {});
|
||||||
patt = MessagePattern("/root/wat","ca.thume.tester","lolwut");
|
patt = MessagePattern("/root/wat","ca.thume.tester","lolwut");
|
||||||
router.setHandler!(int,int)(patt,(int p) {return 6;});
|
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">
|
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>`;
|
<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("/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.thin;
|
||||||
import ddbus.util;
|
import ddbus.util;
|
||||||
import ddbus.c_lib;
|
import ddbus.c_lib;
|
||||||
|
import ddbus.router;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
import std.traits;
|
||||||
|
|
||||||
class PathIface {
|
class PathIface {
|
||||||
this(Connection conn, string dest, string path, string iface) {
|
this(Connection conn, string dest, string path, string iface) {
|
||||||
|
@ -41,3 +43,45 @@ unittest {
|
||||||
names.assertEqual("org.freedesktop.DBus");
|
names.assertEqual("org.freedesktop.DBus");
|
||||||
obj.call!string("GetNameOwner","org.freedesktop.DBus").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