def router()

in pybulletX/robot_interface.py [0:0]


def router(func):
    def upward_wrapper(self):
        childrens_attrs = {}
        for k, v in self.children().items():
            attr = getattr(v, func.__name__)
            if callable(attr):
                childrens_attrs[k] = attr()
            else:
                childrens_attrs[k] = attr
        self_attrs = func(self)

        intersection = set(childrens_attrs.keys()).intersection(self_attrs.keys())
        if intersection:
            raise AttributeError(
                f"Found keys {intersection} in both childrens_attrs and self_attrs"
            )

        attrs = {**childrens_attrs, **self_attrs}
        attrs = _remove_empty_dict_leaf(attrs)

        # TODO(poweic): It's confusing to have both SpaceDict & AttrMap at the same
        # time. Also, return AttrMap in new() method of SpaceDict is weird.
        # Consider creating that's both SpaceDict and AttrMap at the same time.
        if func.__name__ == "get_states":
            attrs = AttrMap(attrs)
        else:
            attrs = SpaceDict(attrs)

        return attrs

    def downward_wrapper(self, attrs):
        children = self.children()
        self_attrs = {k: v for k, v in attrs.items() if k not in children.keys()}
        func(self, self_attrs)

        childrens_attrs = {k: v for k, v in attrs.items() if k in children.keys()}

        for k, v in childrens_attrs.items():
            child = children[k]
            f = getattr(child, func.__name__)
            f(attrs[k])

    if func.__name__ == "set_actions":
        return downward_wrapper
    else:
        return upward_wrapper