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
@@ -21,25 +21,13 @@ var fileDialog: FileDialog = $FileDialog
|
||||
var inspiration_list: InspirationList = $InspirationList
|
||||
|
||||
@onready
|
||||
var soundtrack_label: Label = $VBoxContainer/SoundtrackLabel
|
||||
|
||||
@onready
|
||||
var song_label: Label = $VBoxContainer/SongLabel
|
||||
var now_playing: NowPlaying = $NowPlaying
|
||||
|
||||
@onready
|
||||
var players_panel: PlayersPanel = $PlayersPanel
|
||||
|
||||
@onready
|
||||
var reset_playlist_button: Button = $ResetPlaylistButton
|
||||
|
||||
@onready
|
||||
var reset_points_button: Button = $ResetPointsButton
|
||||
|
||||
@onready
|
||||
var sound_test_button: Button = $SoundTestButton
|
||||
|
||||
@onready
|
||||
var settings_button: Button = $SettingsButton
|
||||
var toolbar: QuizToolbar = $QuizToolbar
|
||||
|
||||
@onready
|
||||
var settings_window: Control = $SettingsWindow
|
||||
@@ -48,10 +36,10 @@ var settings_window: Control = $SettingsWindow
|
||||
var winner_window: Control = %WinnerWindow
|
||||
|
||||
@onready
|
||||
var show_answer_button: Button = $ShowAnswerButton
|
||||
var song_controls: SongControls = $SongControls
|
||||
|
||||
@onready
|
||||
var next_button: Button = $NextButton
|
||||
var song_loader: SongLoader = $SongLoader
|
||||
|
||||
@onready
|
||||
var music_list_panel: MusicListPanel = $MusicListPanel
|
||||
@@ -60,10 +48,7 @@ var music_list_panel: MusicListPanel = $MusicListPanel
|
||||
var new_character_select: Control = %NewCharacterSelect
|
||||
|
||||
@onready
|
||||
var auto_repeat_song_button: CheckButton = $RepeatSongCheckButton
|
||||
|
||||
@onready
|
||||
var music_player_container: PanelContainer = $MusicPlayer
|
||||
var music_player_container: MusicPlayer = $MusicPlayer
|
||||
|
||||
@onready
|
||||
var log_window: Control = %Log
|
||||
@@ -80,9 +65,6 @@ var stats_paused_by_win: bool = false
|
||||
## Dims the window behind an open popup and keeps clicks from reaching the buttons under it.
|
||||
var popup_backdrop: PopupBackdrop
|
||||
|
||||
## Seconds to wait before retrying a song download step that failed.
|
||||
var song_fetch_retry_seconds: float = 5.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
popup_backdrop = PopupBackdrop.add_to(self, _popups())
|
||||
@@ -92,12 +74,14 @@ func _ready() -> void:
|
||||
Settings.is_debug = true
|
||||
settings_window.set_winning_score(5)
|
||||
settings_window.set_selected_server(4)
|
||||
next_button.pressed.connect(play_next_song)
|
||||
show_answer_button.pressed.connect(show_answer_pressed)
|
||||
sound_test_button.pressed.connect(music_player_container.get_sound_test_song)
|
||||
settings_button.pressed.connect(show_settings)
|
||||
reset_playlist_button.pressed.connect(reset_playlist)
|
||||
reset_points_button.pressed.connect(reset_points)
|
||||
song_controls.next_pressed.connect(play_next_song)
|
||||
song_controls.show_answer_pressed.connect(show_answer_pressed)
|
||||
toolbar.sound_test_pressed.connect(music_player_container.get_sound_test_song)
|
||||
toolbar.settings_pressed.connect(show_settings)
|
||||
toolbar.reset_playlist_pressed.connect(reset_playlist)
|
||||
toolbar.reset_points_pressed.connect(reset_points)
|
||||
song_loader.song_list_loaded.connect(update_song_list)
|
||||
song_loader.song_added.connect(_on_song_added)
|
||||
|
||||
new_character_select.connect("new_new_character_selected", _on_new_character_selected)
|
||||
music_list_panel.song_clicked.connect(song_object_clicked)
|
||||
@@ -110,10 +94,9 @@ func _ready() -> void:
|
||||
settings_window.visibility_changed.connect(_on_settings_window_visibility_changed)
|
||||
|
||||
open_button.pressed.connect(open)
|
||||
auto_repeat_song_button.pressed.connect(repeat_song)
|
||||
|
||||
inspiration_list.load_from_server()
|
||||
fetch_song_list_at_start()
|
||||
song_loader.load_song_list()
|
||||
new_character_select.load_characters()
|
||||
|
||||
|
||||
@@ -140,18 +123,15 @@ func _input(event: InputEvent) -> void:
|
||||
|
||||
## Disables the buttons that use the song list while the server syncs it.
|
||||
func lock_for_sync() -> void:
|
||||
sound_test_button.disabled = true
|
||||
reset_playlist_button.disabled = true
|
||||
show_answer_button.disabled = true
|
||||
next_button.disabled = true
|
||||
toolbar.set_locked(true)
|
||||
song_controls.set_locked(true)
|
||||
|
||||
|
||||
## Reloads from the server after a sync and starts a new game.
|
||||
func on_sync_finished() -> void:
|
||||
refresh_from_server()
|
||||
sound_test_button.disabled = false
|
||||
reset_playlist_button.disabled = false
|
||||
show_answer_button.disabled = false
|
||||
toolbar.set_locked(false)
|
||||
song_controls.set_locked(false)
|
||||
reset_points()
|
||||
|
||||
|
||||
@@ -170,41 +150,12 @@ func _on_server_changed() -> void:
|
||||
server_changed.emit()
|
||||
|
||||
|
||||
func repeat_song() -> void:
|
||||
Settings.auto_repeat_song = !Settings.auto_repeat_song
|
||||
|
||||
|
||||
func show_answer_pressed() -> void:
|
||||
print("show_answer_pressed")
|
||||
Playlist.song_is_answered()
|
||||
update_song_list()
|
||||
|
||||
|
||||
# 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 fetch_song_list_at_start() -> void:
|
||||
print("fetch_song_list_at_start")
|
||||
var fetch_song_list_at_start_done: Callable = func fetch_songs_at_start_done(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()
|
||||
update_song_list()
|
||||
if !Playlist.is_song_downloading:
|
||||
fetch_song()
|
||||
MusicServerClient.fetch_song_list(fetch_song_list_at_start_done,
|
||||
_retry_later.bind(fetch_song_list_at_start))
|
||||
|
||||
|
||||
func play_next_song() -> void:
|
||||
print("play_next_song ", Playlist.latest_played_song)
|
||||
if Playlist.first_song_played:
|
||||
@@ -212,9 +163,8 @@ func play_next_song() -> void:
|
||||
Playlist.first_song_played = true
|
||||
music_player_container.play_song_object(Playlist.latest_played_song)
|
||||
if !(Playlist.get_preloaded_songs() > 0):
|
||||
next_button.disabled = true
|
||||
if !Playlist.is_song_downloading:
|
||||
fetch_song()
|
||||
song_controls.set_next_enabled(false)
|
||||
song_loader.fetch_song_if_idle()
|
||||
|
||||
|
||||
func _popups() -> Array[PopupWindow]:
|
||||
@@ -224,63 +174,21 @@ func _popups() -> Array[PopupWindow]:
|
||||
# The cache size can be changed in the settings. Waiting until the settings are closed
|
||||
# avoids starting downloads while the user is still clicking the number up and down.
|
||||
func _on_settings_window_visibility_changed() -> void:
|
||||
if !settings_window.visible && !Playlist.is_song_downloading && Playlist.should_preload_more_songs():
|
||||
fetch_song()
|
||||
if !settings_window.visible:
|
||||
song_loader.fill_cache()
|
||||
|
||||
|
||||
func fetch_song() -> void:
|
||||
print("fetch_song")
|
||||
Playlist.is_song_downloading = true
|
||||
_download_random_song(SongObject.new())
|
||||
|
||||
|
||||
# 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)
|
||||
next_button.disabled = false
|
||||
if Playlist.should_preload_more_songs():
|
||||
fetch_song()
|
||||
else:
|
||||
Playlist.is_song_downloading = false
|
||||
if Settings.is_debug:
|
||||
update_song_list()
|
||||
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" % song_fetch_retry_seconds)
|
||||
get_tree().create_timer(song_fetch_retry_seconds).timeout.connect(step)
|
||||
func _on_song_added() -> void:
|
||||
song_controls.set_next_enabled(true)
|
||||
if Settings.is_debug:
|
||||
update_song_list()
|
||||
|
||||
|
||||
func update_song_list() -> void:
|
||||
print("update_song_list")
|
||||
if Playlist.currently_playing_song >= 0:
|
||||
soundtrack_label.text = Playlist.get_current_soundtrack_title()
|
||||
song_label.text = Playlist.get_current_song_title()
|
||||
now_playing.show_song(Playlist.get_current_soundtrack_title(),
|
||||
Playlist.get_current_song_title())
|
||||
music_list_panel.refresh()
|
||||
|
||||
|
||||
@@ -304,7 +212,7 @@ func reset_playlist() -> void:
|
||||
print("reset_playlist")
|
||||
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
|
||||
Playlist.reset_playlist()
|
||||
fetch_song_list_at_start()
|
||||
song_loader.load_song_list()
|
||||
|
||||
MusicServerClient.reset_playlist(playlist_reset_done)
|
||||
|
||||
|
||||
Reference in new issue
Block a user