1
+ # validated: 2024-01-19 DS e07de37e64f2 ParallelDeadlineGroup.java
1
2
from __future__ import annotations
2
3
3
4
from typing import Dict
4
5
6
+ from wpiutil import SendableBuilder
7
+
5
8
from .command import Command , InterruptionBehavior
6
9
from .commandscheduler import CommandScheduler
7
10
from .exceptions import IllegalCommandUse
10
13
11
14
class ParallelDeadlineGroup (Command ):
12
15
"""
13
- A command composition that runs one of a selection of commands, either using a selector and a key
14
- to command mapping, or a supplier that returns the command directly at runtime.
16
+ A command composition that runs a set of commands in parallel, ending only when a specific
17
+ command (the "deadline") ends, interrupting all other commands that are still running at that
18
+ point.
15
19
16
20
The rules for command compositions apply: command instances that are passed to it cannot be
17
21
added to any other composition or scheduled individually, and the composition requires all
18
- subsystems its components require."""
22
+ subsystems its components require.
23
+ """
19
24
20
25
def __init__ (self , deadline : Command , * commands : Command ):
21
26
"""
22
- Creates a new SelectCommand.
27
+ Creates a new ParallelDeadlineGroup. The given commands (including the
28
+ deadline) will be executed simultaneously. The composition will finish when
29
+ the deadline finishes, interrupting all other still-running commands. If
30
+ the composition is interrupted, only the commands still running will be
31
+ interrupted.
32
+
33
+ :param deadline: the command that determines when the composition ends
34
+ :param commands: the commands to be executed
23
35
24
- :param commands: the map of commands to choose from
25
- :param selector: the selector to determine which command to run """
36
+ :raises IllegalCommandUse: if the deadline command is also in the otherCommands argument
37
+ """
26
38
super ().__init__ ()
27
39
self ._commands : Dict [Command , bool ] = {}
28
40
self ._runsWhenDisabled = True
29
41
self ._finished = True
30
- self ._deadline = deadline
31
42
self ._interruptBehavior = InterruptionBehavior .kCancelIncoming
32
43
self .addCommands (* commands )
33
- if deadline not in self ._commands :
34
- self .addCommands (deadline )
44
+ self .setDeadline (deadline )
35
45
36
46
def setDeadline (self , deadline : Command ):
37
- if deadline not in self ._commands :
38
- self .addCommands (deadline )
47
+ """
48
+ Sets the deadline to the given command. The deadline is added to the group if it is not already
49
+ contained.
50
+
51
+ :param deadline: the command that determines when the group ends
52
+
53
+ :raises IllegalCommandUse: if the deadline command is already in the composition
54
+ """
55
+
56
+ # use getattr here because deadline not set in constructor
57
+ isAlreadyDeadline = deadline == getattr (self , "_deadline" , None )
58
+ if isAlreadyDeadline :
59
+ return
60
+
61
+ if deadline in self ._commands :
62
+ raise IllegalCommandUse (
63
+ f"The deadline command cannot also be in the other commands!"
64
+ )
65
+ self .addCommands (deadline )
39
66
self ._deadline = deadline
40
67
41
68
def addCommands (self , * commands : Command ):
69
+ """
70
+ Adds the given commands to the group.
71
+
72
+ :param commands: Commands to add to the group.
73
+
74
+ :raises IllegalCommandUse: if the deadline command is already in the composition
75
+ """
42
76
commands = flatten_args_commands (commands )
43
77
if not self ._finished :
44
78
raise IllegalCommandUse (
@@ -50,7 +84,7 @@ def addCommands(self, *commands: Command):
50
84
for command in commands :
51
85
if not command .getRequirements ().isdisjoint (self .requirements ):
52
86
raise IllegalCommandUse (
53
- "Multiple comands in a parallel composition cannot require the same subsystems."
87
+ "Multiple commands in a parallel composition cannot require the same subsystems."
54
88
)
55
89
56
90
self ._commands [command ] = False
@@ -94,3 +128,10 @@ def runsWhenDisabled(self) -> bool:
94
128
95
129
def getInterruptionBehavior (self ) -> InterruptionBehavior :
96
130
return self ._interruptBehavior
131
+
132
+ def initSendable (self , builder : SendableBuilder ):
133
+ super ().initSendable (builder )
134
+
135
+ builder .addStringProperty (
136
+ "deadline" , lambda : self ._deadline .getName (), lambda _ : None
137
+ )
0 commit comments