robotengine.signal

Signal 是 robotengine 实现节点间通信和异步调用的基础。

 1"""
 2
 3Signal 是 robotengine 实现节点间通信和异步调用的基础。
 4
 5"""
 6
 7from typing import Callable
 8from robotengine.tools import warning
 9import threading
10
11class Signal:
12    """ 信号类 """
13    def __init__(self, *param_types):
14        """ 
15        初始化信号,需要指定信号的参数类型以保证信号触发时的类型安全,例如:
16
17            signal = Signal(int, float, str)
18
19        如果是复杂的类型,则要使用 python 库中的 typing 模块,例如:
20
21            from typing import List, Dict
22
23            signal = Signal(List[int], Dict[str, float])
24
25        """
26        self._callbacks = []
27        self._param_types = param_types  # 存储信号的预期参数类型
28
29    def connect(self, callback: Callable):
30        """ 连接信号,需要指定一个回调函数 """
31        if callback not in self._callbacks:
32            self._callbacks.append(callback)
33        else:
34            warning(f"{callback} 已经存在,请勿重复添加")
35
36    def disconnect(self, callback: Callable):
37        """ 断开信号,需要指定一个回调函数 """
38        if callback in self._callbacks:
39            self._callbacks.remove(callback)
40        else:
41            warning(f"{callback} 不存在,请勿重复删除")
42
43    def emit(self, *args, **kwargs):
44        """ 
45        触发信号,需要指定信号的参数 
46
47        注意,信号触发后执行的回调函数是异步的,不会阻塞主线程。
48
49        """
50        if len(args) != len(self._param_types):
51            raise TypeError(f"Expected {len(self._param_types)} arguments, but got {len(args)}")
52
53        for expected_type, actual_arg in zip(self._param_types, args):
54            if not isinstance(actual_arg, expected_type):
55                raise TypeError(f"Expected argument of type {expected_type}, but got {type(actual_arg)}")
56
57        new_thread = threading.Thread(target=self._emit, args=args, kwargs=kwargs, daemon=True)
58        new_thread.start()
59    
60    def _emit(self, *args, **kwargs):
61        for callback in self._callbacks:
62            callback(*args, **kwargs)
63
64    def __repr__(self):
65        return f"Signal(connected callbacks={len(self._callbacks)})"
class Signal:
12class Signal:
13    """ 信号类 """
14    def __init__(self, *param_types):
15        """ 
16        初始化信号,需要指定信号的参数类型以保证信号触发时的类型安全,例如:
17
18            signal = Signal(int, float, str)
19
20        如果是复杂的类型,则要使用 python 库中的 typing 模块,例如:
21
22            from typing import List, Dict
23
24            signal = Signal(List[int], Dict[str, float])
25
26        """
27        self._callbacks = []
28        self._param_types = param_types  # 存储信号的预期参数类型
29
30    def connect(self, callback: Callable):
31        """ 连接信号,需要指定一个回调函数 """
32        if callback not in self._callbacks:
33            self._callbacks.append(callback)
34        else:
35            warning(f"{callback} 已经存在,请勿重复添加")
36
37    def disconnect(self, callback: Callable):
38        """ 断开信号,需要指定一个回调函数 """
39        if callback in self._callbacks:
40            self._callbacks.remove(callback)
41        else:
42            warning(f"{callback} 不存在,请勿重复删除")
43
44    def emit(self, *args, **kwargs):
45        """ 
46        触发信号,需要指定信号的参数 
47
48        注意,信号触发后执行的回调函数是异步的,不会阻塞主线程。
49
50        """
51        if len(args) != len(self._param_types):
52            raise TypeError(f"Expected {len(self._param_types)} arguments, but got {len(args)}")
53
54        for expected_type, actual_arg in zip(self._param_types, args):
55            if not isinstance(actual_arg, expected_type):
56                raise TypeError(f"Expected argument of type {expected_type}, but got {type(actual_arg)}")
57
58        new_thread = threading.Thread(target=self._emit, args=args, kwargs=kwargs, daemon=True)
59        new_thread.start()
60    
61    def _emit(self, *args, **kwargs):
62        for callback in self._callbacks:
63            callback(*args, **kwargs)
64
65    def __repr__(self):
66        return f"Signal(connected callbacks={len(self._callbacks)})"

信号类

Signal(*param_types)
14    def __init__(self, *param_types):
15        """ 
16        初始化信号,需要指定信号的参数类型以保证信号触发时的类型安全,例如:
17
18            signal = Signal(int, float, str)
19
20        如果是复杂的类型,则要使用 python 库中的 typing 模块,例如:
21
22            from typing import List, Dict
23
24            signal = Signal(List[int], Dict[str, float])
25
26        """
27        self._callbacks = []
28        self._param_types = param_types  # 存储信号的预期参数类型

初始化信号,需要指定信号的参数类型以保证信号触发时的类型安全,例如:

signal = Signal(int, float, str)

如果是复杂的类型,则要使用 python 库中的 typing 模块,例如:

from typing import List, Dict

signal = Signal(List[int], Dict[str, float])
def connect(self, callback: Callable):
30    def connect(self, callback: Callable):
31        """ 连接信号,需要指定一个回调函数 """
32        if callback not in self._callbacks:
33            self._callbacks.append(callback)
34        else:
35            warning(f"{callback} 已经存在,请勿重复添加")

连接信号,需要指定一个回调函数

def disconnect(self, callback: Callable):
37    def disconnect(self, callback: Callable):
38        """ 断开信号,需要指定一个回调函数 """
39        if callback in self._callbacks:
40            self._callbacks.remove(callback)
41        else:
42            warning(f"{callback} 不存在,请勿重复删除")

断开信号,需要指定一个回调函数

def emit(self, *args, **kwargs):
44    def emit(self, *args, **kwargs):
45        """ 
46        触发信号,需要指定信号的参数 
47
48        注意,信号触发后执行的回调函数是异步的,不会阻塞主线程。
49
50        """
51        if len(args) != len(self._param_types):
52            raise TypeError(f"Expected {len(self._param_types)} arguments, but got {len(args)}")
53
54        for expected_type, actual_arg in zip(self._param_types, args):
55            if not isinstance(actual_arg, expected_type):
56                raise TypeError(f"Expected argument of type {expected_type}, but got {type(actual_arg)}")
57
58        new_thread = threading.Thread(target=self._emit, args=args, kwargs=kwargs, daemon=True)
59        new_thread.start()

触发信号,需要指定信号的参数

注意,信号触发后执行的回调函数是异步的,不会阻塞主线程。