12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
+ from types import TracebackType
16
+ from typing import Any , Generic , List , Optional , Type , TYPE_CHECKING , TypeVar
17
+
18
+
19
+ from rclpy .impl .implementation_singleton import rclpy_implementation as _rclpy
20
+
21
+ T = TypeVar ('T' )
22
+
23
+
24
+ if TYPE_CHECKING :
25
+ from typing_extensions import Self
26
+
27
+ from rclpy .callback_groups import CallbackGroup
28
+ from rclpy .task import Future
29
+
15
30
16
31
class NumberOfEntities :
17
32
@@ -24,8 +39,8 @@ class NumberOfEntities:
24
39
'num_events' ]
25
40
26
41
def __init__ (
27
- self , num_subs = 0 , num_gcs = 0 , num_timers = 0 ,
28
- num_clients = 0 , num_services = 0 , num_events = 0
42
+ self , num_subs : int = 0 , num_gcs : int = 0 , num_timers : int = 0 ,
43
+ num_clients : int = 0 , num_services : int = 0 , num_events : int = 0
29
44
):
30
45
self .num_subscriptions = num_subs
31
46
self .num_guard_conditions = num_gcs
@@ -34,7 +49,7 @@ def __init__(
34
49
self .num_services = num_services
35
50
self .num_events = num_events
36
51
37
- def __add__ (self , other ) :
52
+ def __add__ (self , other : 'NumberOfEntities' ) -> 'NumberOfEntities' :
38
53
result = self .__class__ ()
39
54
result .num_subscriptions = self .num_subscriptions + other .num_subscriptions
40
55
result .num_guard_conditions = self .num_guard_conditions + other .num_guard_conditions
@@ -44,7 +59,7 @@ def __add__(self, other):
44
59
result .num_events = self .num_events + other .num_events
45
60
return result
46
61
47
- def __iadd__ (self , other ) :
62
+ def __iadd__ (self , other : 'NumberOfEntities' ) -> 'NumberOfEntities' :
48
63
self .num_subscriptions += other .num_subscriptions
49
64
self .num_guard_conditions += other .num_guard_conditions
50
65
self .num_timers += other .num_timers
@@ -53,59 +68,64 @@ def __iadd__(self, other):
53
68
self .num_events += other .num_events
54
69
return self
55
70
56
- def __repr__ (self ):
71
+ def __repr__ (self ) -> str :
57
72
return '<{0}({1}, {2}, {3}, {4}, {5}, {6})>' .format (
58
73
self .__class__ .__name__ , self .num_subscriptions ,
59
74
self .num_guard_conditions , self .num_timers , self .num_clients ,
60
75
self .num_services , self .num_events )
61
76
62
77
63
- class Waitable :
78
+ class Waitable ( Generic [ T ]) :
64
79
"""
65
80
Add something to a wait set and execute it.
66
81
67
82
This class wraps a collection of entities which can be added to a wait set.
68
83
"""
69
84
70
- def __init__ (self , callback_group ):
85
+ def __init__ (self , callback_group : 'CallbackGroup' ):
71
86
# A callback group to control when this entity can execute (used by Executor)
72
87
self .callback_group = callback_group
73
88
self .callback_group .add_entity (self )
74
89
# Flag set by executor when a handler has been created but not executed (used by Executor)
75
90
self ._executor_event = False
76
91
# List of Futures that have callbacks needing execution
77
- self ._futures = []
92
+ self ._futures : List [ Future [ Any ]] = []
78
93
79
- def __enter__ (self ):
94
+ def __enter__ (self ) -> 'Self' :
80
95
"""Implement to mark entities as in-use to prevent destruction while waiting on them."""
81
- pass
96
+ raise NotImplementedError ( 'Must be implemented by subclass' )
82
97
83
- def __exit__ (self , t , v , tb ):
98
+ def __exit__ (
99
+ self ,
100
+ exc_type : Optional [Type [BaseException ]],
101
+ exc_val : Optional [BaseException ],
102
+ exc_tb : Optional [TracebackType ],
103
+ ) -> None :
84
104
"""Implement to mark entities as not-in-use to allow destruction after waiting on them."""
85
- pass
105
+ raise NotImplementedError ( 'Must be implemented by subclass' )
86
106
87
- def add_future (self , future ) :
107
+ def add_future (self , future : 'Future[Any]' ) -> None :
88
108
self ._futures .append (future )
89
109
90
- def remove_future (self , future ) :
110
+ def remove_future (self , future : 'Future[Any]' ) -> None :
91
111
self ._futures .remove (future )
92
112
93
- def is_ready (self , wait_set ) :
113
+ def is_ready (self , wait_set : _rclpy . WaitSet ) -> bool :
94
114
"""Return True if entities are ready in the wait set."""
95
115
raise NotImplementedError ('Must be implemented by subclass' )
96
116
97
- def take_data (self ):
117
+ def take_data (self ) -> T :
98
118
"""Take stuff from lower level so the wait set doesn't immediately wake again."""
99
119
raise NotImplementedError ('Must be implemented by subclass' )
100
120
101
- async def execute (self , taken_data ) :
121
+ async def execute (self , taken_data : T ) -> None :
102
122
"""Execute work after data has been taken from a ready wait set."""
103
123
raise NotImplementedError ('Must be implemented by subclass' )
104
124
105
- def get_num_entities (self ):
125
+ def get_num_entities (self ) -> NumberOfEntities :
106
126
"""Return number of each type of entity used."""
107
127
raise NotImplementedError ('Must be implemented by subclass' )
108
128
109
- def add_to_wait_set (self , wait_set ) :
129
+ def add_to_wait_set (self , wait_set : _rclpy . WaitSet ) -> None :
110
130
"""Add entities to wait set."""
111
131
raise NotImplementedError ('Must be implemented by subclass' )
0 commit comments