def compute_param_updates(subscribers, param_key, param_value):
    """
    Compute subscribers that should be notified based on the parameter update
    @param subscribers: parameter subscribers
    @type  subscribers: Registrations
    @param param_key: parameter key
    @type  param_key: str
    @param param_value: parameter value
    @type  param_value: str
    """
    
    # logic correct for both updates and deletions

    if not subscribers:
        return []
    
    # end with a trailing slash to optimize startswith check from
    # needing an extra equals check
    if param_key != SEP:
        param_key = canonicalize_name(param_key) + SEP    

    # compute all the updated keys
    if type(param_value) == dict:
        all_keys = _compute_all_keys(param_key, param_value)
    else:
        all_keys = None
        
    updates = []
    
    # subscriber gets update if anything in the subscribed namespace is updated or if its deleted
    for sub_key in subscribers.iterkeys():
        ns_key = sub_key
        if ns_key[-1] != SEP:
            ns_key = sub_key + SEP
        if param_key.startswith(ns_key):
            node_apis = subscribers[sub_key]
            updates.append((node_apis, param_key, param_value))
        elif all_keys is not None and ns_key.startswith(param_key) \
             and not sub_key in all_keys:
            # parameter was deleted
            node_apis = subscribers[sub_key]
            updates.append((node_apis, sub_key, {}))

    # add updates for exact matches within tree
    if all_keys is not None:
        # #586: iterate over parameter tree for notification
        for key in all_keys:
            if key in subscribers:
                # compute actual update value
                sub_key = key[len(param_key):]
                namespaces = [x for x in sub_key.split(SEP) if x]
                val = param_value
                for ns in namespaces:
                    val = val[ns]

                updates.append((subscribers[key], key, val))

    return updates
        
Esempio n. 2
0
def compute_param_updates(subscribers, param_key, param_value):
    """
    Compute subscribers that should be notified based on the parameter update
    @param subscribers: parameter subscribers
    @type  subscribers: Registrations
    @param param_key: parameter key
    @type  param_key: str
    @param param_value: parameter value
    @type  param_value: str
    """
    
    # logic correct for both updates and deletions

    if not subscribers:
        return []
    
    # end with a trailing slash to optimize startswith check from
    # needing an extra equals check
    if param_key != SEP:
        param_key = canonicalize_name(param_key) + SEP    

    # compute all the updated keys
    if type(param_value) == dict:
        all_keys = _compute_all_keys(param_key, param_value)
    else:
        all_keys = None
        
    updates = []
    
    # subscriber gets update if anything in the subscribed namespace is updated or if its deleted
    for sub_key in subscribers.iterkeys():
        ns_key = sub_key
        if ns_key[-1] != SEP:
            ns_key = sub_key + SEP
        if param_key.startswith(ns_key):
            node_apis = subscribers[sub_key]
            updates.append((node_apis, param_key, param_value))
        elif all_keys is not None and ns_key.startswith(param_key) \
             and not sub_key in all_keys:
            # parameter was deleted
            node_apis = subscribers[sub_key]
            updates.append((node_apis, sub_key, {}))

    # add updates for exact matches within tree
    if all_keys is not None:
        # #586: iterate over parameter tree for notification
        for key in all_keys:
            if key in subscribers:
                # compute actual update value
                sub_key = key[len(param_key):]
                namespaces = [x for x in sub_key.split(SEP) if x]
                val = param_value
                for ns in namespaces:
                    val = val[ns]

                updates.append((subscribers[key], key, val))

    return updates
 def unsubscribe_param(self, key, unregistration_args):
     """
     @param key str: parameter key
     @type  key: str
     @param unregistration_args: additional args to pass to
     subscribers.unregister. i.e. unregister will be called with
     (key, *unregistration_args)
     @type  unregistration_args: tuple
     @return: return value of subscribers.unregister()
     """
     if key != SEP:
         key = canonicalize_name(key) + SEP
     return self.reg_manager.unregister_param_subscriber(key, *unregistration_args)
Esempio n. 4
0
 def add_remap(self, remap):
     """
     Add a new remap setting to the context. if a remap already
     exists with the same from key, it will be removed
     
     @param remap: remap setting
     @type  remap: (str, str)
     """
     remap = [canonicalize_name(x) for x in remap]
     if not remap[0] or not remap[1]:
         raise RLException("remap from/to attributes cannot be empty")
     if not is_legal_name(remap[0]):
         raise RLException("remap from [%s] is not a valid ROS name"%remap[0])
     if not is_legal_name(remap[1]):
         raise RLException("remap to [%s] is not a valid ROS name"%remap[1])
     
     matches = [r for r in self._remap_args if r[0] == remap[0]]
     for m in matches:
         self._remap_args.remove(m)
     self._remap_args.append(remap)
Esempio n. 5
0
 def add_remap(self, remap):
     """
     Add a new remap setting to the context. if a remap already
     exists with the same from key, it will be removed
     
     @param remap: remap setting
     @type  remap: (str, str)
     """
     remap = [canonicalize_name(x) for x in remap]
     if not remap[0] or not remap[1]:
         raise RLException("remap from/to attributes cannot be empty")
     if not is_legal_name(remap[0]):
         raise RLException("remap from [%s] is not a valid ROS name"%remap[0])
     if not is_legal_name(remap[1]):
         raise RLException("remap to [%s] is not a valid ROS name"%remap[1])
     
     matches = [r for r in self._remap_args if r[0] == remap[0]]
     for m in matches:
         self._remap_args.remove(m)
     self._remap_args.append(remap)
Esempio n. 6
0
def test_canonicalize_name():
    from rosgraph.names import canonicalize_name
    tests = [
        ('', ''),
        ('/', '/'),
        ('foo', 'foo'),
        ('/foo', '/foo'),
        ('/foo/', '/foo'),
        ('/foo/bar', '/foo/bar'),
        ('/foo/bar/', '/foo/bar'),
        ('/foo/bar//', '/foo/bar'),
        ('/foo//bar', '/foo/bar'),
        ('//foo/bar', '/foo/bar'),
        ('foo/bar', 'foo/bar'),
        ('foo//bar', 'foo/bar'),
        ('foo/bar/', 'foo/bar'),
        ('/foo/bar', '/foo/bar'),
    ]
    for t, v in tests:
        assert v == canonicalize_name(t)
Esempio n. 7
0
def test_canonicalize_name():
    from rosgraph.names import canonicalize_name
    tests = [
        ('', ''),
        ('/', '/'),
        ('foo', 'foo'),          
        ('/foo', '/foo'),          
        ('/foo/', '/foo'),
        ('/foo/bar', '/foo/bar'),
        ('/foo/bar/', '/foo/bar'),
        ('/foo/bar//', '/foo/bar'),
        ('/foo//bar', '/foo/bar'),
        ('//foo/bar', '/foo/bar'),
        ('foo/bar', 'foo/bar'),
        ('foo//bar', 'foo/bar'),
        ('foo/bar/', 'foo/bar'),
        ('/foo/bar', '/foo/bar'),
        ]
    for t, v in tests:
        assert v == canonicalize_name(t)
 def subscribe_param(self, key, registration_args):
     """
     @param key: parameter key
     @type  key: str
     @param registration_args: additional args to pass to
     subscribers.register. First parameter is always the parameter
     key.
     @type  registration_args: tuple
     """
     if key != SEP:
         key = canonicalize_name(key) + SEP
     try:
         self.lock.acquire()
         # fetch parameter value
         try:
             val = self.get_param(key)
         except KeyError:
             # parameter not set yet
             val = {}
         self.reg_manager.register_param_subscriber(key, *registration_args)
         return val
     finally:
         self.lock.release()