Split now playing, the quiz buttons and song loading out of the quiz
NowPlaying, QuizToolbar and SongControls become their own scenes, the auto repeat switch moves into the music player scene, and downloading songs moves into a SongLoader node. The quiz only wires the parts together. Every node keeps its place on screen. Screenshots of every UI state are pixel-identical to before, the layout test still matches the original baseline, and each new part has its own tests.
This commit is contained in:
1 parent
bad4b3ad8b
commit
e94c75e84d
32 files changed
+822
-300
No files matched your search
+100
@@ -0,0 +1,100 @@
|
||||
class_name SongLoader
|
||||
extends Node
|
||||
## Downloads songs from the server into the Playlist ahead of time, so the next song
|
||||
## can start at once.
|
||||
##
|
||||
## How many songs it keeps ready is the cache size in the settings
|
||||
## ([code]Playlist.number_of_tracks_to_preload[/code]).
|
||||
|
||||
## Emitted when the songs already in the server playlist have been loaded into the
|
||||
## Playlist.
|
||||
signal song_list_loaded
|
||||
|
||||
## Emitted when a new song has been downloaded and added to the Playlist.
|
||||
signal song_added
|
||||
|
||||
## Seconds to wait before retrying a download step that failed.
|
||||
var retry_seconds: float = 5.0
|
||||
|
||||
|
||||
## Loads the songs already in the server playlist, then starts preloading new ones.
|
||||
## Preloading waits for the list, because loading the list clears the playlist.
|
||||
func load_song_list() -> void:
|
||||
print("load_song_list")
|
||||
var song_list_fetched: Callable = func song_list_fetched(data) -> void:
|
||||
Playlist.clear_song_list()
|
||||
if typeof(data) == TYPE_ARRAY:
|
||||
for d: Dictionary in data:
|
||||
var new_song_object: SongObject = SongObject.new()
|
||||
new_song_object.song_number = d.SongNo
|
||||
new_song_object.soundtrack_title = d.Soundtrack
|
||||
new_song_object.song_title = d.Song
|
||||
new_song_object.is_answered = true
|
||||
new_song_object.has_played = true
|
||||
Playlist.add_to_playlist(new_song_object)
|
||||
elif data != null:
|
||||
print("Unexpected data")
|
||||
Playlist.update_last_played_song()
|
||||
song_list_loaded.emit()
|
||||
fetch_song_if_idle()
|
||||
MusicServerClient.fetch_song_list(song_list_fetched, _retry_later.bind(load_song_list))
|
||||
|
||||
|
||||
## Starts downloading one more song, which keeps downloading until the cache is full.
|
||||
func fetch_song() -> void:
|
||||
print("fetch_song")
|
||||
Playlist.is_song_downloading = true
|
||||
_download_random_song(SongObject.new())
|
||||
|
||||
|
||||
## Starts downloading a song unless one is already downloading.
|
||||
func fetch_song_if_idle() -> void:
|
||||
if !Playlist.is_song_downloading:
|
||||
fetch_song()
|
||||
|
||||
|
||||
## Starts downloading if nothing is downloading and the cache is not full, e.g. after
|
||||
## the cache size was raised.
|
||||
func fill_cache() -> void:
|
||||
if !Playlist.is_song_downloading && Playlist.should_preload_more_songs():
|
||||
fetch_song()
|
||||
|
||||
|
||||
# Fetching a song takes three requests. If one fails, only that step is retried, so
|
||||
# the server and the game keep the same songs in their playlists.
|
||||
func _download_random_song(new_song_object: SongObject) -> void:
|
||||
var song_downloaded: Callable = func song_downloaded(body: PackedByteArray) -> void:
|
||||
print("song_downloaded")
|
||||
var sound: AudioStream = AudioStreamMP3.new()
|
||||
sound.data = body
|
||||
new_song_object.song = sound
|
||||
_add_song_to_queue(new_song_object)
|
||||
MusicServerClient.fetch_random_song(Settings.use_low_played_mode, song_downloaded,
|
||||
_retry_later.bind(_download_random_song.bind(new_song_object)))
|
||||
|
||||
|
||||
func _add_song_to_queue(new_song_object: SongObject) -> void:
|
||||
MusicServerClient.add_to_queue(_fetch_song_info.bind(new_song_object),
|
||||
_retry_later.bind(_add_song_to_queue.bind(new_song_object)))
|
||||
|
||||
|
||||
func _fetch_song_info(new_song_object: SongObject) -> void:
|
||||
var song_info_fetched: Callable = func song_info_fetched(data_received: Dictionary) -> void:
|
||||
print("song_info_fetched")
|
||||
new_song_object.song_number = data_received.SongNo
|
||||
new_song_object.soundtrack_title = data_received.Soundtrack
|
||||
new_song_object.song_title = data_received.Song
|
||||
print("new_song_object: ", new_song_object.to_string())
|
||||
Playlist.add_to_playlist(new_song_object)
|
||||
if Playlist.should_preload_more_songs():
|
||||
fetch_song()
|
||||
else:
|
||||
Playlist.is_song_downloading = false
|
||||
song_added.emit()
|
||||
MusicServerClient.fetch_song_info(song_info_fetched,
|
||||
_retry_later.bind(_fetch_song_info.bind(new_song_object)))
|
||||
|
||||
|
||||
func _retry_later(step: Callable) -> void:
|
||||
print("Song download failed, retrying in %s seconds" % retry_seconds)
|
||||
get_tree().create_timer(retry_seconds).timeout.connect(step)
|
||||
Reference in new issue
Block a user