Skip to content

Commit

Permalink
Update score reels for proper asyncio code, v0.57.0.dev30
Browse files Browse the repository at this point in the history
fixes #1721
  • Loading branch information
toomanybrians committed Oct 25, 2023
1 parent 175868b commit 4054259
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 36 deletions.
2 changes: 1 addition & 1 deletion mpf/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""

__version__ = '0.57.0.dev29' # Also consider whether MPF-MC pyproject.toml should be updated
__version__ = '0.57.0.dev30' # Also consider whether MPF-MC pyproject.toml should be updated
'''The full version of MPF.'''

__short_version__ = '0.57'
Expand Down
29 changes: 8 additions & 21 deletions mpf/devices/score_reel_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ def __init__(self, machine):
self.machine.events.add_handler('player_score', self._score_change)

# receives notifications of game starts to reset the reels
self.machine.events.add_handler('game_starting', self._game_starting)
self.machine.events.add_async_handler('game_starting', self._game_starting)

# receives notifications of game ends to reset the reels
self.machine.events.add_handler('game_ending', self._game_ending)

# Need to hook this in case reels aren't done when ball ends
self.machine.events.add_handler('ball_ending', self._ball_ending, 900)
self.machine.events.add_async_handler('ball_ending', self._ball_ending, 900)

def _rotate_player(self, **kwargs):
"""Start a new player's turn.
Expand Down Expand Up @@ -123,7 +123,7 @@ def _score_change(self, value, change, player_num, **kwargs):
# set value
score_reel_group.set_value(value=value)

def _game_starting(self, queue, **kwargs):
async def _game_starting(self, **kwargs):
"""Reset the score reels when a new game starts.
This is a queue event so it doesn't allow the game start to continue
Expand All @@ -134,8 +134,6 @@ def _game_starting(self, queue, **kwargs):
queue: A reference to the queue object for the game starting event.
"""
del kwargs
# tell the game_starting event queue that we have stuff to do
queue.wait()

# calculate a player <-> reel mapping
for player_num in range(1, self.machine.game.max_players + 1):
Expand All @@ -156,17 +154,9 @@ def _game_starting(self, queue, **kwargs):
futures = []
for score_reel_group in self.machine.score_reel_groups.values():
score_reel_group.set_value(0)
futures.append(score_reel_group.wait_for_ready())
await score_reel_group.wait_for_ready()

future = asyncio.wait(iter(futures))
future = asyncio.ensure_future(future)
future.add_done_callback(partial(self._reels_ready, queue=queue))

@staticmethod
def _reels_ready(future, queue):
"""Unblock queue since all reels are ready."""
del future
queue.clear()
await asyncio.gather(*futures)

def _game_ending(self, **kwargs):
"""Reset controller."""
Expand All @@ -176,11 +166,8 @@ def _game_ending(self, **kwargs):
self.active_scorereelgroup = None
self.player_to_scorereel_map = {}

def _ball_ending(self, queue=None, **kwargs):
async def _ball_ending(self, **kwargs):
del kwargs
# We need to hook the ball_ending event in case the ball ends while the
# score reel is still catching up.
queue.wait()

future = asyncio.ensure_future(self.active_scorereelgroup.wait_for_ready())
future.add_done_callback(partial(self._reels_ready, queue=queue))
for score_reel_group in self.machine.score_reel_groups.values():
await score_reel_group.wait_for_ready()
10 changes: 3 additions & 7 deletions mpf/devices/score_reel_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,10 @@ def set_value(self, value):

self.reels[i].set_destination_value(self.desired_value_list[i])

def wait_for_ready(self):
async def wait_for_ready(self):
"""Return a future which will be done when all reels reached their destination."""
futures = []
for reel in self.reels:
if reel:
futures.append(reel.wait_for_ready())

return asyncio.wait(iter(futures))
futures = [reel.wait_for_ready() for reel in self.reels if reel]
await asyncio.gather(*futures)

def int_to_reel_list(self, value):
"""Convert an integer to a list of integers that represent each positional digit in this ScoreReelGroup.
Expand Down
8 changes: 1 addition & 7 deletions mpf/tests/test_ScoreReels.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def get_machine_path(self):
def _synchronise_to_reel(self):
pass

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def testOvershooting(self):
player1_10k = self.machine.coils["player1_10k"].hw_driver
player1_1k = self.machine.coils["player1_1k"].hw_driver
Expand Down Expand Up @@ -93,7 +92,6 @@ def testOvershooting(self):
self.assertEqual(2, player1_100.pulse.call_count)
self.assertEqual(1, player1_10.pulse.call_count)

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def testScoring(self):
player1_10k = self.machine.coils["player1_10k"].hw_driver
player1_1k = self.machine.coils["player1_1k"].hw_driver
Expand Down Expand Up @@ -215,7 +213,6 @@ def testScoring(self):
self.assertEqual(10, player1_10.pulse.call_count)
self.assertEqual(1, chime1.pulse.call_count)

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def testAdvanceingFailure(self):
player1_10k = self.machine.coils["player1_10k"].hw_driver
player1_1k = self.machine.coils["player1_1k"].hw_driver
Expand Down Expand Up @@ -260,7 +257,6 @@ def testAdvanceingFailure(self):
self.assertEqual(3, player1_100.pulse.call_count)
self.assertEqual(1, player1_10.pulse.call_count)

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def testThreePlayers(self):
player1_10k = self.machine.coils["player1_10k"].hw_driver
player1_1k = self.machine.coils["player1_1k"].hw_driver
Expand Down Expand Up @@ -387,7 +383,6 @@ def get_platform(self):
def get_machine_path(self):
return 'tests/machine_files/score_reels/'

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def testScoringVirtual(self):
self.machine.playfield.add_ball = MagicMock()
self.machine.ball_controller.num_balls_known = 3
Expand Down Expand Up @@ -429,7 +424,6 @@ def testScoringVirtual(self):
self.assertSwitchState("score_1p_10_9", 0)
self.assertSwitchState("score_1p_100_9", 1)

@unittest.skipIf(sys.version_info >= (3, 11), "Score reels are not working in Python 3.11+")
def test_inactive_player_scoring(self):
self.start_two_player_game()
self.assertGameIsRunning()
Expand Down Expand Up @@ -483,7 +477,7 @@ def test_inactive_player_scoring(self):
self.advance_time_and_run()
self.assertGameIsRunning()
self.assertEqual(0, self.machine.game.num_players)
self.advance_time_and_run()
self.advance_time_and_run(5)
self.assertEqual(1, self.machine.game.num_players)
self.hit_and_release_switch("s_start")
self.advance_time_and_run(1)
Expand Down

0 comments on commit 4054259

Please sign in to comment.