def testMatchCallbackWildcards(self): def callback(m): pass n = dispatch.AddressNode() n.addCallback("/foo/*", callback) self.assertEquals(n.matchCallbacks(osc.Message("/foo")), set()) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar")), set([callback])) self.assertEquals(n.matchCallbacks(osc.Message("/bar")), set()) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar/baz")), set([])) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar")), set([callback])) n = dispatch.AddressNode() n.addCallback("/*", callback) self.assertEquals(n.matchCallbacks(osc.Message("/")), set([callback])) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar")), set([])) n = dispatch.AddressNode() n.addCallback("/*/baz", callback) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar")), set()) self.assertEquals(n.matchCallbacks(osc.Message("/foo/baz")), set([callback])) n = dispatch.AddressNode() n.addCallback("/*/*", callback) self.assertEquals(n.matchCallbacks(osc.Message("/foo/baz")), set([callback])) self.assertEquals(n.matchCallbacks(osc.Message("/foo/bar/baz")), set([]))
def testName(self): n = dispatch.AddressNode() n.setName("the_name") self.assertEquals("the_name", n.getName()) n = dispatch.AddressNode("the_name") self.assertEquals("the_name", n.getName())
def testAddressNodeRenaming(self): def cb(): pass child = dispatch.AddressNode() child.addCallback("/bar", cb) parent = dispatch.AddressNode() parent.addNode("foo", child) self.assertEquals(parent.getCallbacks("/foo/bar"), set([cb])) child.setName("bar") self.assertEquals(parent.getCallbacks("/bar/bar"), set([cb]))
def testMatchMessageWithWildcards(self): def fooCallback(m): pass def barCallback(m): pass def bazCallback(m): pass def foobarCallback(m): pass n = dispatch.AddressNode() n.addCallback("/foo", fooCallback) n.addCallback("/bar", barCallback) n.addCallback("/baz", bazCallback) n.addCallback("/foo/bar", foobarCallback) self.assertEquals(n.matchCallbacks(osc.Message("/*")), set([fooCallback, barCallback, bazCallback])) self.assertEquals(n.matchCallbacks(osc.Message("/spam")), set()) self.assertEquals(n.matchCallbacks(osc.Message("/ba*")), set([barCallback, bazCallback])) self.assertEquals(n.matchCallbacks(osc.Message("/b*r")), set([barCallback])) self.assertEquals(n.matchCallbacks(osc.Message("/ba?")), set([barCallback, bazCallback]))
def __init__(self, touchosc_interface, handler_name, tabpage_names): """ Initialize a TabpageHandler object. @type tabpage_names: C{list} @param tabpage_names: List of tabpages that this handler will handle. @type handler_name: C{str} @param handler_name: Name to be registered with the TouchOscInterface """ self.ros_name = rospy.get_name() self.handler_name = handler_name self.parent = touchosc_interface if type(tabpage_names) is str: self.tabpage_names = [tabpage_names] elif type(tabpage_names) is list: self.tabpage_names = tabpage_names else: raise ValueError("type(tabpage_names) is not str or list") self.osc_node = {} for name in self.tabpage_names: self.osc_node[name] = {} self.osc_node[name][None] = dispatch.AddressNode(name) self.ros_publishers = {} self.ros_subscribers = {}
def testAddressNodeReparenting(self): def cb(): pass child = dispatch.AddressNode() child.addCallback("/bar", cb) baz = dispatch.AddressNode() parent = dispatch.AddressNode() parent.addNode("foo", child) parent.addNode("baz", baz) # empty node self.assertEquals(parent.getCallbacks("/foo/bar"), set([cb])) child.setParent(baz) self.assertEquals(parent.getCallbacks("/foo/bar"), set([])) self.assertEquals(parent.getCallbacks("/baz/foo/bar"), set([cb]))
def add_osc_callback(self, name, control_callback, tabpages=None, z_callback=None): """ Convenience function for adding OSC callbacks. Users are welcome to use the txosc API for adding their own callbacks, but this tends to make it simpler for TouchOSC controls. control_callback and z_callback must have the function signature: C{callback(address_list, value_list, send_address)} @param name: control name (as addressed) @type name: C{string} @param control_callback: callback function to be called upon match. @type control_callback: Function @keyword tabpages: A tabpage name or list of tabpage names (namespaces) to add this control to. If not passed, then the callback will default to all tabpage names that are associated with this handler. @type tabpages: C{str} or C{list} @keyword z_callback: callback function to be called upon control name z-state change. In order for this to work, "Send Z messages" must be enabled on the TouchOSC app. @type z_callback: function """ if type(tabpages) is list: iter_tabpages = tabpages elif type(tabpages) is str: iter_tabpages = [tabpages] else: iter_tabpages = self.tabpage_names for tabpage in iter_tabpages: if tabpage not in self.tabpage_names: rospy.logwarn("Tried to add control %s to tabpage %s" % (name, tabpage)) rospy.logwarn("Cannot add callbacks to an unaliased tabage") continue node = self.osc_node[tabpage] node[name] = dispatch.AddressNode(name) # Match /tabpage/control value node[name].addCallback("*", control_callback) if z_callback is not None: # Match /tabpage/control/z value node[name].addCallback("/z", z_callback) # Match /tabpage/control/2/z value node[name].addCallback("/[0-9]+/z", z_callback) # Match /tabpage/control/2 value node[name].addCallback("/[0-9]+", control_callback) # Match /tabpage/control/2/2 value node[name].addCallback("/[0-9]+/[0-9]+", control_callback) else: # Match /tabpage/control/z value # Match /tabpage/control/2 value node[name].addCallback("/*", control_callback) # Match /tabpage/control/2/2 value node[name].addCallback("/*/*", control_callback) node[None].addNode(name, node[name])
def testMatchExact(self): def callback(m): pass n = dispatch.AddressNode() n.addCallback("/foo", callback) self.assertEquals(n.matchCallbacks(osc.Message("/foo")), set([callback])) self.assertEquals(n.matchCallbacks(osc.Message("/bar")), set())
def testRemoveAllCallbacks(self): def callback(m): pass def callback2(m): pass def callback3(m): pass n = dispatch.AddressNode() n.addCallback("/foo", callback) self.assertEquals(n.getCallbacks("/*"), set([callback])) n.removeAllCallbacks() self.assertEquals(n.getCallbacks("/*"), set()) n = dispatch.AddressNode() n.addCallback("/foo", callback) n.addCallback("/foo/bar", callback2) n.removeAllCallbacks() self.assertEquals(n.getCallbacks("/*"), set([]))
def testAddRemoveCallback(self): def callback(m): pass n = dispatch.AddressNode() n.addCallback("/foo", callback) self.assertEquals(n.getCallbacks("/foo"), set([callback])) n.removeCallback("/foo", callback) self.assertEquals(n.getCallbacks("/foo"), set()) n.addCallback("/*", callback) self.assertEquals(n.getCallbacks("/foo"), set([callback])) n.removeCallback("/*", callback) self.assertEquals(n.getCallbacks("/foo"), set())
def testMatchMessageWithRange(self): def firstCallback(m): pass def secondCallback(m): pass n = dispatch.AddressNode() n.addCallback("/foo/1", firstCallback) n.addCallback("/foo/2", secondCallback) self.assertEquals(n.matchCallbacks(osc.Message("/baz")), set()) self.assertEquals(n.matchCallbacks(osc.Message("/foo/[1-3]")), set([firstCallback, secondCallback])) self.assertEquals(n.matchCallbacks(osc.Message("/foo/[!1]")), set([secondCallback]))
def testMatchCallbackRangeWildcards(self): def callback1(m): pass def callback2(m): pass n = dispatch.AddressNode() n.addCallback("/foo1", callback1) n.addCallback("/foo2", callback2) self.assertEquals(n.matchCallbacks(osc.Message("/foo[1]")), set([callback1])) self.assertEquals(n.matchCallbacks(osc.Message("/foo[1-9]")), set([callback1, callback2])) self.assertEquals(n.matchCallbacks(osc.Message("/foo[4-6]")), set([]))
def testAddressNodeNestingMultiple(self): class MyNode(dispatch.AddressNode): def __init__(self): dispatch.AddressNode.__init__(self) self.addCallback("/trigger", self.trigger) def trigger(self): pass c1 = MyNode() c2 = MyNode() parent = dispatch.AddressNode() parent.addNode("foo", c1) parent.addNode("bar", c2) self.assertEquals(parent.getCallbacks("/foo/*"), set([c1.trigger])) self.assertEquals(parent.getCallbacks("/bar/*"), set([c2.trigger])) self.assertEquals(parent.getCallbacks("/*/trigger"), set([c1.trigger, c2.trigger]))
def testFallback(self): """ Tests how fallbacks are handled. """ foo = osc.Message("/foo") egg_spam = osc.Message("/egg/spam") egg_ham = osc.Message("/egg/ham") addr = ("0.0.0.0", 17778) called = {'foo': False, 'egg_spam': False, 'fallback': False} def foo_cb(message, a): self.assertEquals(message, foo) self.assertEquals(addr, a) called['foo'] = True def egg_spam_cb(message, a): self.assertEquals(message, egg_spam) self.assertEquals(addr, a) called['egg_spam'] = True def fallback(message, a): self.assertEquals(message, egg_ham) self.assertEquals(addr, a) called['fallback'] = True recv = dispatch.Receiver() recv.addCallback("/foo", foo_cb) child = dispatch.AddressNode() child.addCallback("/spam", egg_spam_cb) recv.addNode("egg", child) recv.fallback = fallback # now, dispatch messages recv.dispatch(foo, addr) recv.dispatch(egg_spam, addr) recv.dispatch(egg_ham, addr) self.assertTrue(called['foo']) self.assertTrue(called['egg_spam']) self.assertTrue(called['fallback'])
def testRemoveNonExistingCallback(self): n = dispatch.AddressNode() self.assertRaises(KeyError, n.removeCallback, "/foo", lambda m: m)
def testAddInvalidCallback(self): n = dispatch.AddressNode() self.assertRaises(ValueError, n.addCallback, "/foo bar/baz", lambda m: m) self.assertEquals(n.addCallback("/foo/*/baz", lambda m: m), None)