Skip to content

Commit

Permalink
Merge pull request #1352 from missionpinball/delay_registry_and_uvloop
Browse files Browse the repository at this point in the history
do not depend on python asyncio internals. fix crash in bonus mode wi…
  • Loading branch information
jabdoa2 committed Apr 30, 2019
2 parents ccb8ddf + 205743b commit 0f31aa0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
34 changes: 18 additions & 16 deletions mpf/core/delays.py
Expand Up @@ -2,7 +2,7 @@

import uuid
from functools import partial
from typing import Any, Callable, Dict
from typing import Any, Callable, Dict, Tuple
from mpf.core.mpf_controller import MpfController

MYPY = False # noqa
Expand Down Expand Up @@ -31,7 +31,7 @@ class DelayManager(MpfController):

def __init__(self, machine: "MachineController") -> None:
"""Initialise delay manager."""
self.delays = {} # type: Dict[str, Any]
self.delays = {} # type: Dict[str, Tuple[Any, Callable]]
super().__init__(machine)

def add(self, ms: int, callback: Callable[..., None], name: str = None,
Expand All @@ -57,13 +57,16 @@ def add(self, ms: int, callback: Callable[..., None], name: str = None,
self.debug_log("Adding delay. Name: '%s' ms: %s, callback: %s, "
"kwargs: %s", name, ms, callback, kwargs)

if name in self.delays:
self.machine.clock.unschedule(self.delays[name])
del self.delays[name]
try:
delay = self.delays.pop(name)
except KeyError:
pass
else:
self.machine.clock.unschedule(delay[0])

self.delays[name] = self.machine.clock.schedule_once(
self.delays[name] = (self.machine.clock.schedule_once(
partial(self._process_delay_callback, name, callback, **kwargs),
ms / 1000.0)
ms / 1000.0), callback)

return name

Expand All @@ -78,12 +81,12 @@ def remove(self, name: str):
delay with this name, that's ok. Nothing happens.
"""
self.debug_log("Removing delay: '%s'", name)
if name in self.delays:
self.machine.clock.unschedule(self.delays[name])
try:
del self.delays[name]
except KeyError:
pass
try:
delay = self.delays.pop(name)
except KeyError:
pass
else:
self.machine.clock.unschedule(delay[0])

def add_if_doesnt_exist(self, ms: int, callback: Callable[..., None],
name: str, **kwargs) -> str:
Expand Down Expand Up @@ -149,7 +152,7 @@ def reset(self, ms: int, callback: Callable[..., None], name: str,
def clear(self) -> None:
"""Remove (clear) all the delays associated with this DelayManager."""
for name in list(self.delays.keys()):
self.machine.clock.unschedule(self.delays[name])
self.machine.clock.unschedule(self.delays[name][0])
self.remove(name)

self.delays = {}
Expand All @@ -168,8 +171,7 @@ def run_now(self, name: str):
# have to save the callback ref first, since if the callback
# schedules a new delay with the same name, then the removal
# will remove it
# pylint: disable-msg=protected-access
cb = self.delays[name]._callback
cb = self.delays[name][1]
self.remove(name)
cb()
except KeyError:
Expand Down
12 changes: 12 additions & 0 deletions mpf/tests/test_Delay.py
Expand Up @@ -61,6 +61,18 @@ def test_check(self):
self.assertTrue(self.machine.delay.check('delay_test'))
self.assertFalse(self.machine.delay.check('delay_test_fake'))

def test_double_add(self):
self.callback = MagicMock()
# add delay
self.machine.delay.add(100, self.callback, "delay_test")
self.advance_time_and_run(.05)
# add same name again. it should reset the time
self.machine.delay.add(100, self.callback, "delay_test")
self.advance_time_and_run(.06)
self.callback.assert_not_called()
self.advance_time_and_run(.05)
self.callback.assert_any_call()

def test_reset(self):
self.callback = MagicMock()
self.machine.delay.add(1000, self.callback, "delay_test")
Expand Down

0 comments on commit 0f31aa0

Please sign in to comment.