[gnome-music/mcatanzaro/random-shuffle] Make random shuffle actually random
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/mcatanzaro/random-shuffle] Make random shuffle actually random
- Date: Thu, 19 Aug 2021 17:16:12 +0000 (UTC)
commit 79f142723ab0d7f8925e7a5b0f1fe2166cebaaea
Author: Michael Catanzaro <mcatanzaro redhat com>
Date: Thu Aug 19 12:12:07 2021 -0500
Make random shuffle actually random
Currently the randomness in the random shuffle is implemented by
returning a random result in a sort function, which is not very random
at all. In practice, it results in songs close to the start of the list
being sorted first.
To fix this, we can simply assign a random integer to each song and
compare them in the sorting function, to make the results consistent.
Yes, I know this probably isn't a great way to implement a random
shuffle in a music player app. We would probably want to write our own
list model to handle smarts like "don't sort two songs from the same
artist next to each other." But that requires effort, whereas what I've
done here is simple and works.
gnomemusic/coresong.py | 6 ++++++
gnomemusic/player.py | 7 ++++---
2 files changed, 10 insertions(+), 3 deletions(-)
---
diff --git a/gnomemusic/coresong.py b/gnomemusic/coresong.py
index 064a6f8d7..94d548aa0 100644
--- a/gnomemusic/coresong.py
+++ b/gnomemusic/coresong.py
@@ -24,6 +24,7 @@
from __future__ import annotations
from enum import IntEnum
+from random import randint
from typing import Optional
import typing
@@ -50,6 +51,7 @@ class CoreSong(GObject.GObject):
media = GObject.Property(type=Grl.Media)
grlid = GObject.Property(type=str, default=None)
play_count = GObject.Property(type=int)
+ shuffle_pos = GObject.Property(type=int)
state = GObject.Property() # FIXME: How to set an IntEnum type?
title = GObject.Property(type=str)
track_number = GObject.Property(type=int)
@@ -82,6 +84,7 @@ class CoreSong(GObject.GObject):
self._is_tracker: bool = media.get_source() == "grl-tracker3-source"
self.props.validation = CoreSong.Validation.PENDING
self.update(media)
+ self.update_shuffle_pos()
def __eq__(self, other: object) -> bool:
return (isinstance(other, CoreSong)
@@ -175,3 +178,6 @@ class CoreSong(GObject.GObject):
self.props.media.set_last_played(GLib.DateTime.new_now_utc())
self._coregrilo.writeback_tracker(
self.props.media, "last-played")
+
+ def update_shuffle_pos(self) -> None:
+ self.props.shuffle_pos = randint(1, 1_000_000)
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 7e6ddf289..372d30103 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -24,7 +24,7 @@
from enum import Enum, IntEnum
from gettext import gettext as _
-from random import randint, randrange
+from random import randrange
import time
import typing
@@ -277,11 +277,12 @@ class PlayerPlaylist(GObject.GObject):
self._model_recent.set_offset(offset)
def _on_repeat_mode_changed(self, klass, param):
- # FIXME: This shuffle is too simple.
def _shuffle_sort(song_a, song_b):
- return randint(-1, 1)
+ return song_a.shuffle_pos < song_b.shuffle_pos
if self.props.repeat_mode == RepeatMode.SHUFFLE:
+ for idx, coresong in enumerate(self._model):
+ coresong.update_shuffle_pos()
self._model.set_sort_func(
utils.wrap_list_store_sort_func(_shuffle_sort))
elif self.props.repeat_mode in [RepeatMode.NONE, RepeatMode.ALL]:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]