Fix song counter and inconsistent queue state
This commit is contained in:
2 files changed
+45
-7
No files matched your search
@@ -25,15 +25,36 @@ class MusicPlayerQueueTest(unittest.IsolatedAsyncioTestCase):
|
|||||||
self.assertIs(voice_client.playing, track)
|
self.assertIs(voice_client.playing, track)
|
||||||
self.assertEqual(player.state(GUILD).index, 0)
|
self.assertEqual(player.state(GUILD).index, 0)
|
||||||
|
|
||||||
async def test_single_play_budget_drops_track_from_queue(self):
|
async def test_last_play_remains_pointed_to_until_playback_finishes(self):
|
||||||
player, _ = build_player(default_plays=1)
|
player, _ = build_player(default_plays=1)
|
||||||
track = FakeTrack("a")
|
track = FakeTrack("a")
|
||||||
await player.enqueue(GUILD, track)
|
await player.enqueue(GUILD, track)
|
||||||
|
|
||||||
state = player.state(GUILD)
|
state = player.state(GUILD)
|
||||||
|
self.assertEqual(state.queue, [track])
|
||||||
|
self.assertEqual(state.index, 0)
|
||||||
|
self.assertIs(state.current, track)
|
||||||
|
|
||||||
|
await player.play_next(GUILD, advance=True)
|
||||||
|
|
||||||
self.assertEqual(state.queue, [])
|
self.assertEqual(state.queue, [])
|
||||||
self.assertEqual(state.index, -1)
|
self.assertEqual(state.index, -1)
|
||||||
self.assertIs(state.current, track)
|
self.assertIsNone(state.current)
|
||||||
|
|
||||||
|
async def test_last_play_of_recreated_track_is_removed_after_callback(self):
|
||||||
|
player, _, state = await self._queue_abc(default_plays=2)
|
||||||
|
state.loop_mode = LoopMode.TRACK
|
||||||
|
|
||||||
|
await player.play_next(GUILD, advance=True)
|
||||||
|
self.assertEqual([track.id for track in state.queue], ["a", "b", "c"])
|
||||||
|
self.assertEqual(state.index, 0)
|
||||||
|
self.assertEqual(state.current.plays_left, 0)
|
||||||
|
|
||||||
|
await player.play_next(GUILD, advance=True)
|
||||||
|
|
||||||
|
self.assertEqual([track.id for track in state.queue], ["b", "c"])
|
||||||
|
self.assertEqual(state.index, 0)
|
||||||
|
self.assertEqual(state.current.id, "b")
|
||||||
|
|
||||||
async def test_enqueue_while_playing_only_appends(self):
|
async def test_enqueue_while_playing_only_appends(self):
|
||||||
_, _, state = await self._queue_abc()
|
_, _, state = await self._queue_abc()
|
||||||
|
|||||||
@@ -189,12 +189,30 @@ class MusicPlayer:
|
|||||||
if state.consume_jump():
|
if state.consume_jump():
|
||||||
advance = False
|
advance = False
|
||||||
|
|
||||||
|
# Utwór z ostatnim odtworzeniem musi pozostać w kolejce do chwili
|
||||||
|
# zakończenia źródła. W przeciwnym razie panel dostaje `current`, ale
|
||||||
|
# `queue_index` wskazuje pozycję spoza kolejki podczas faktycznego
|
||||||
|
# odtwarzania ostatniej kopii.
|
||||||
|
retired_index: int | None = None
|
||||||
|
if advance and state.current is not None and 0 <= state.index < len(state.queue):
|
||||||
|
current = state.queue[state.index]
|
||||||
|
if current is state.current and self.plays_left(current) <= 0:
|
||||||
|
retired_index = state.index
|
||||||
|
state.queue.pop(state.index)
|
||||||
|
state.index -= 1
|
||||||
|
|
||||||
if not state.queue:
|
if not state.queue:
|
||||||
state.index = -1
|
state.index = -1
|
||||||
state.current = None
|
state.current = None
|
||||||
|
await self.trigger_state_change()
|
||||||
return
|
return
|
||||||
|
|
||||||
next_index = self._next_index(state, advance=advance)
|
if retired_index is not None:
|
||||||
|
next_index = retired_index
|
||||||
|
if state.loop_mode.loops_queue:
|
||||||
|
next_index %= len(state.queue)
|
||||||
|
else:
|
||||||
|
next_index = self._next_index(state, advance=advance)
|
||||||
if next_index >= len(state.queue):
|
if next_index >= len(state.queue):
|
||||||
state.index = next_index
|
state.index = next_index
|
||||||
state.current = None
|
state.current = None
|
||||||
@@ -220,13 +238,12 @@ class MusicPlayer:
|
|||||||
track.plays_left = self.plays_left(track) - 1
|
track.plays_left = self.plays_left(track) - 1
|
||||||
track.volume = state.volume
|
track.volume = state.volume
|
||||||
|
|
||||||
|
state.queue[next_index] = track
|
||||||
if track.plays_left <= 0:
|
if track.plays_left <= 0:
|
||||||
state.queue.pop(next_index)
|
# Usunięcie nastąpi dopiero po callbacku discord.py, po tym jak
|
||||||
state.index = next_index - 1
|
# ostatnie odtworzenie rzeczywiście się zakończy.
|
||||||
if state.loop_mode.loops_track:
|
if state.loop_mode.loops_track:
|
||||||
state.loop_mode = LoopMode.OFF
|
state.loop_mode = LoopMode.OFF
|
||||||
else:
|
|
||||||
state.queue[next_index] = track
|
|
||||||
|
|
||||||
state.current = track
|
state.current = track
|
||||||
self._record_history(guild_id, track)
|
self._record_history(guild_id, track)
|
||||||
|
|||||||
Reference in new issue
Block a user