Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove concurrent avoiding modification member variables (Python) #66

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 7 additions & 37 deletions commands2/commandscheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,6 @@ def __init__(self) -> None:
self._interruptActions: List[Callable[[Command, Optional[Command]], None]] = []
self._finishActions: List[Callable[[Command], None]] = []

self._inRunLoop = False
self._toSchedule: Dict[Command, None] = {}
# python: toCancelInterruptors stored in _toCancel dict
self._toCancel: Dict[Command, Optional[Command]] = {}
# self._toCancelInterruptors: List[Optional[Command]] = []
self._endingCommands: Set[Command] = set()

self._watchdog = Watchdog(TimedRobot.kDefaultPeriod, lambda: None)

hal.report(
Expand Down Expand Up @@ -187,10 +180,6 @@ def _schedule(self, command: Optional[Command]) -> None:
reportWarning("Tried to schedule a null command!", True)
return

if self._inRunLoop:
self._toSchedule[command] = None
return

self.requireNotComposed(command)

# Do nothing if the scheduler is disabled, the robot is disabled and the command
Expand Down Expand Up @@ -259,11 +248,15 @@ def run(self) -> None:
loopCache.poll()
self._watchdog.addEpoch("buttons.run()")

self._inRunLoop = True
isDisabled = RobotState.isDisabled()

# Run scheduled commands, remove finished commands.
for command in self._scheduledCommands.copy():
if not self.isScheduled(command):
# skip as the normal scheduledCommands was modified
# and that command was canceled
continue

if isDisabled and not command.runsWhenDisabled():
self._cancel(command, None)
continue
Expand All @@ -273,28 +266,14 @@ def run(self) -> None:
action(command)
self._watchdog.addEpoch(f"{command.getName()}.execute()")
if command.isFinished():
self._endingCommands.add(command)
self._scheduledCommands.pop(command)
command.end(False)
for action in self._finishActions:
action(command)
self._endingCommands.remove(command)
self._scheduledCommands.pop(command)
for requirement in command.getRequirements():
self._requirements.pop(requirement)
self._watchdog.addEpoch(f"{command.getName()}.end(False)")

self._inRunLoop = False

# Schedule/cancel commands from queues populated during loop
for command in self._toSchedule:
self._schedule(command)

for command, interruptor in self._toCancel.items():
self._cancel(command, interruptor)

self._toSchedule.clear()
self._toCancel.clear()

# Add default commands for un-required registered subsystems.
for subsystem, scommand in self._subsystems.items():
if subsystem not in self._requirements and scommand is not None:
Expand Down Expand Up @@ -425,23 +404,14 @@ def _cancel(self, command: Command, interruptor: Optional[Command]):
reportWarning("Tried to cancel a null command", True)
return

if command in self._endingCommands:
return

if self._inRunLoop:
self._toCancel[command] = interruptor
return

if not self.isScheduled(command):
return

self._endingCommands.add(command)
self._scheduledCommands.pop(command)
command.end(True)
for action in self._interruptActions:
action(command, interruptor)

self._endingCommands.remove(command)
self._scheduledCommands.pop(command)
for requirement in command.getRequirements():
del self._requirements[requirement]
self._watchdog.addEpoch(f"{command.getName()}.end(true)")
Expand Down