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
+15
-6
@@ -1,14 +1,16 @@
|
||||
class_name MusicPlayer
|
||||
extends PanelContainer
|
||||
extends Control
|
||||
## The bar that plays the songs, with play, restart, progress and volume, and the
|
||||
## auto repeat switch under it.
|
||||
|
||||
# LOC 20/1-24: 136
|
||||
# LOC 12/6-24: 170
|
||||
|
||||
@onready
|
||||
var play_button: TextureButton = $MusicPlayerContainer/PlayTextureButton
|
||||
var play_button: TextureButton = $PlayerBar/MusicPlayerContainer/PlayTextureButton
|
||||
|
||||
@onready
|
||||
var restart_button: TextureButton = $MusicPlayerContainer/RestartTextureButton
|
||||
var restart_button: TextureButton = $PlayerBar/MusicPlayerContainer/RestartTextureButton
|
||||
|
||||
@onready
|
||||
var audio_player: AudioStreamPlayer = $AudioStreamPlayer
|
||||
@@ -20,13 +22,16 @@ var sound_player: AudioStreamPlayer = $AudioSoundPlayer
|
||||
var sound_effect_player: AudioStreamPlayer = $AudioSoundEffectPlayer
|
||||
|
||||
@onready
|
||||
var progress_slider: HSlider = $MusicPlayerContainer/MusicPlayerSlider
|
||||
var progress_slider: HSlider = $PlayerBar/MusicPlayerContainer/MusicPlayerSlider
|
||||
|
||||
@onready
|
||||
var volume_slider: HSlider = $MusicPlayerContainer/VolumeSlider
|
||||
var volume_slider: HSlider = $PlayerBar/MusicPlayerContainer/VolumeSlider
|
||||
|
||||
@onready
|
||||
var music_time_label: Label = $MusicPlayerContainer/MusicTimeLabel
|
||||
var music_time_label: Label = $PlayerBar/MusicPlayerContainer/MusicTimeLabel
|
||||
|
||||
@onready
|
||||
var auto_repeat_button: CheckButton = $RepeatSongCheckButton
|
||||
|
||||
var play_icon: Texture = preload("res://icons/play_icon_light.svg")
|
||||
var pause_icon: Texture = preload("res://icons/pause_icon_light.svg")
|
||||
@@ -49,6 +54,10 @@ func _ready() -> void:
|
||||
progress_slider.drag_ended.connect(_on_drag_ended)
|
||||
|
||||
audio_player.finished.connect(_on_finished)
|
||||
auto_repeat_button.pressed.connect(_on_auto_repeat_pressed)
|
||||
|
||||
func _on_auto_repeat_pressed() -> void:
|
||||
Settings.auto_repeat_song = !Settings.auto_repeat_song
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if audio_player.has_stream_playback() && !is_changing && !audio_player.stream_paused:
|
||||
|
||||
+27
-19
@@ -26,19 +26,11 @@ unicode = 90
|
||||
[sub_resource type="Shortcut" id="Shortcut_i7swq"]
|
||||
events = [SubResource("InputEventKey_2nvce")]
|
||||
|
||||
[node name="MusicPlayer" type="PanelContainer"]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -121.0
|
||||
offset_top = -15.5
|
||||
offset_right = 121.0
|
||||
offset_bottom = 16.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_vertical = 4
|
||||
[node name="MusicPlayer" type="Control"]
|
||||
layout_mode = 3
|
||||
offset_right = 1792.0
|
||||
offset_bottom = 71.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_t24ra")
|
||||
|
||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||
@@ -53,11 +45,17 @@ bus = &"music"
|
||||
stream = ExtResource("2_xti80")
|
||||
bus = &"music"
|
||||
|
||||
[node name="MusicPlayerContainer" type="HBoxContainer" parent="."]
|
||||
[node name="PlayerBar" type="PanelContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 1.0
|
||||
offset_right = 1792.0
|
||||
offset_bottom = 32.0
|
||||
|
||||
[node name="MusicPlayerContainer" type="HBoxContainer" parent="PlayerBar"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="PlayTextureButton" type="TextureButton" parent="MusicPlayerContainer"]
|
||||
[node name="PlayTextureButton" type="TextureButton" parent="PlayerBar/MusicPlayerContainer"]
|
||||
custom_minimum_size = Vector2(32, 32)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
@@ -67,7 +65,7 @@ texture_normal = ExtResource("3_6g308")
|
||||
ignore_texture_size = true
|
||||
stretch_mode = 0
|
||||
|
||||
[node name="RestartTextureButton" type="TextureButton" parent="MusicPlayerContainer"]
|
||||
[node name="RestartTextureButton" type="TextureButton" parent="PlayerBar/MusicPlayerContainer"]
|
||||
custom_minimum_size = Vector2(32, 32)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
@@ -78,17 +76,27 @@ ignore_texture_size = true
|
||||
stretch_mode = 0
|
||||
flip_h = true
|
||||
|
||||
[node name="MusicPlayerSlider" type="HSlider" parent="MusicPlayerContainer"]
|
||||
[node name="MusicPlayerSlider" type="HSlider" parent="PlayerBar/MusicPlayerContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 4
|
||||
scrollable = false
|
||||
|
||||
[node name="MusicTimeLabel" type="Label" parent="MusicPlayerContainer"]
|
||||
[node name="MusicTimeLabel" type="Label" parent="PlayerBar/MusicPlayerContainer"]
|
||||
layout_mode = 2
|
||||
text = "0:00 / 0:00"
|
||||
|
||||
[node name="VolumeSlider" parent="MusicPlayerContainer" instance=ExtResource("5_iifuj")]
|
||||
[node name="VolumeSlider" parent="PlayerBar/MusicPlayerContainer" instance=ExtResource("5_iifuj")]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="RepeatSongCheckButton" type="CheckButton" parent="."]
|
||||
layout_mode = 0
|
||||
offset_top = 40.0
|
||||
offset_right = 144.0
|
||||
offset_bottom = 71.0
|
||||
focus_mode = 0
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Auto repeat"
|
||||
@@ -0,0 +1,29 @@
|
||||
[gd_scene format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://now_playing.gd" id="part_script"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_qspbu"]
|
||||
font_size = 50
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_3m52w"]
|
||||
font_size = 35
|
||||
|
||||
[node name="NowPlaying" type="VBoxContainer" unique_id=42468498]
|
||||
layout_mode = 3
|
||||
offset_right = 1088.0
|
||||
offset_bottom = 320.0
|
||||
script = ExtResource("part_script")
|
||||
|
||||
[node name="SoundtrackLabel" type="Label" parent="." unique_id=173147793]
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_qspbu")
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="SongLabel" type="Label" parent="." unique_id=1687490027]
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_3m52w")
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
@@ -9,30 +9,10 @@
|
||||
[ext_resource type="PackedScene" path="res://MusicListPanel.tscn" id="scene_MusicListPanel"]
|
||||
[ext_resource type="PackedScene" path="res://PlayersPanel.tscn" id="scene_PlayersPanel"]
|
||||
[ext_resource type="PackedScene" path="res://InspirationList.tscn" id="scene_InspirationList"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_qspbu"]
|
||||
font_size = 50
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_3m52w"]
|
||||
font_size = 35
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_06rl4"]
|
||||
device = -1
|
||||
alt_pressed = true
|
||||
keycode = 86
|
||||
unicode = 8249
|
||||
|
||||
[sub_resource type="Shortcut" id="Shortcut_a7fvb"]
|
||||
events = [SubResource("InputEventKey_06rl4")]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_7dnqw"]
|
||||
device = -1
|
||||
alt_pressed = true
|
||||
keycode = 67
|
||||
unicode = 231
|
||||
|
||||
[sub_resource type="Shortcut" id="Shortcut_d6fml"]
|
||||
events = [SubResource("InputEventKey_7dnqw")]
|
||||
[ext_resource type="PackedScene" path="res://QuizToolbar.tscn" id="scene_QuizToolbar"]
|
||||
[ext_resource type="PackedScene" path="res://SongControls.tscn" id="scene_SongControls"]
|
||||
[ext_resource type="PackedScene" path="res://NowPlaying.tscn" id="scene_NowPlaying"]
|
||||
[ext_resource type="Script" path="res://song_loader.gd" id="song_loader_script"]
|
||||
|
||||
[node name="Quiz" type="Control" unique_id=1146705218]
|
||||
layout_mode = 3
|
||||
@@ -76,40 +56,19 @@ offset_top = 128.0
|
||||
offset_right = 1857.0
|
||||
offset_bottom = 512.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=42468498]
|
||||
[node name="NowPlaying" parent="." unique_id=42468498 instance=ExtResource("scene_NowPlaying")]
|
||||
layout_mode = 0
|
||||
offset_left = 64.0
|
||||
offset_top = 64.0
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 384.0
|
||||
|
||||
[node name="SoundtrackLabel" type="Label" parent="VBoxContainer" unique_id=173147793]
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_qspbu")
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="SongLabel" type="Label" parent="VBoxContainer" unique_id=1687490027]
|
||||
custom_minimum_size = Vector2(1, 1)
|
||||
layout_mode = 2
|
||||
label_settings = SubResource("LabelSettings_3m52w")
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="MusicPlayer" parent="." unique_id=1990459832 instance=ExtResource("5_emn36")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = 65.0
|
||||
offset_left = 64.0
|
||||
offset_top = 992.0
|
||||
offset_right = 1856.0
|
||||
offset_bottom = 1024.0
|
||||
grow_horizontal = 1
|
||||
grow_vertical = 1
|
||||
offset_bottom = 1063.0
|
||||
|
||||
[node name="PlayersPanel" parent="." unique_id=1708375945 instance=ExtResource("scene_PlayersPanel")]
|
||||
layout_mode = 0
|
||||
@@ -118,68 +77,19 @@ offset_top = 576.0
|
||||
offset_right = 1857.0
|
||||
offset_bottom = 977.0
|
||||
|
||||
[node name="ResetPlaylistButton" type="Button" parent="." unique_id=1754155620]
|
||||
[node name="QuizToolbar" parent="." unique_id=1873301941 instance=ExtResource("scene_QuizToolbar")]
|
||||
layout_mode = 0
|
||||
offset_left = 1360.0
|
||||
offset_top = 64.0
|
||||
offset_right = 1471.0
|
||||
offset_bottom = 95.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Reset playlist"
|
||||
|
||||
[node name="ResetPointsButton" type="Button" parent="." unique_id=942880776]
|
||||
layout_mode = 0
|
||||
offset_left = 1488.0
|
||||
offset_top = 64.0
|
||||
offset_right = 1599.0
|
||||
offset_bottom = 95.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Reset points"
|
||||
|
||||
[node name="SoundTestButton" type="Button" parent="." unique_id=1332971879]
|
||||
layout_mode = 0
|
||||
offset_left = 1744.0
|
||||
offset_top = 64.0
|
||||
offset_right = 1855.0
|
||||
offset_bottom = 95.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Sound test"
|
||||
|
||||
[node name="ShowAnswerButton" type="Button" parent="." unique_id=415388039]
|
||||
[node name="SongControls" parent="." unique_id=1640212773 instance=ExtResource("scene_SongControls")]
|
||||
layout_mode = 0
|
||||
offset_left = 65.0
|
||||
offset_top = 944.0
|
||||
offset_right = 176.0
|
||||
offset_bottom = 975.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
shortcut = SubResource("Shortcut_a7fvb")
|
||||
text = "Show answer"
|
||||
|
||||
[node name="NextButton" type="Button" parent="." unique_id=1744703488]
|
||||
layout_mode = 0
|
||||
offset_left = 193.0
|
||||
offset_top = 944.0
|
||||
offset_right = 368.0
|
||||
offset_bottom = 975.0
|
||||
focus_mode = 0
|
||||
disabled = true
|
||||
action_mode = 0
|
||||
shortcut = SubResource("Shortcut_d6fml")
|
||||
text = "Randomize new track"
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="." unique_id=1193400323]
|
||||
layout_mode = 0
|
||||
offset_left = 1616.0
|
||||
offset_top = 64.0
|
||||
offset_right = 1727.0
|
||||
offset_bottom = 95.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Settings"
|
||||
|
||||
[node name="SettingsWindow" parent="." unique_id=1323246978 instance=ExtResource("11_k62u5")]
|
||||
visible = false
|
||||
@@ -207,17 +117,6 @@ offset_top = 153.0
|
||||
offset_right = 720.0
|
||||
offset_bottom = 153.0
|
||||
|
||||
[node name="RepeatSongCheckButton" type="CheckButton" parent="." unique_id=776835053]
|
||||
layout_mode = 0
|
||||
offset_left = 64.0
|
||||
offset_top = 1032.0
|
||||
offset_right = 208.0
|
||||
offset_bottom = 1063.0
|
||||
focus_mode = 0
|
||||
button_pressed = true
|
||||
action_mode = 0
|
||||
text = "Auto repeat"
|
||||
|
||||
[node name="DebugLabel" type="Label" parent="." unique_id=1959221257]
|
||||
visible = false
|
||||
layout_mode = 0
|
||||
@@ -240,4 +139,7 @@ offset_top = 132.0
|
||||
offset_right = 1262.0
|
||||
offset_bottom = 832.0
|
||||
|
||||
[node name="SongLoader" type="Node" parent="." unique_id=1520867349]
|
||||
script = ExtResource("song_loader_script")
|
||||
|
||||
[connection signal="dir_selected" from="FileDialog" to="." method="_on_file_dialog_dir_selected"]
|
||||
@@ -0,0 +1,45 @@
|
||||
[gd_scene format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://quiz_toolbar.gd" id="part_script"]
|
||||
|
||||
[node name="QuizToolbar" type="Control" unique_id=1873301941]
|
||||
layout_mode = 3
|
||||
offset_right = 495.0
|
||||
offset_bottom = 31.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource("part_script")
|
||||
|
||||
[node name="ResetPlaylistButton" type="Button" parent="." unique_id=1754155620]
|
||||
layout_mode = 0
|
||||
offset_right = 111.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Reset playlist"
|
||||
|
||||
[node name="ResetPointsButton" type="Button" parent="." unique_id=942880776]
|
||||
layout_mode = 0
|
||||
offset_left = 128.0
|
||||
offset_right = 239.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Reset points"
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="." unique_id=1193400323]
|
||||
layout_mode = 0
|
||||
offset_left = 256.0
|
||||
offset_right = 367.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Settings"
|
||||
|
||||
[node name="SoundTestButton" type="Button" parent="." unique_id=1332971879]
|
||||
layout_mode = 0
|
||||
offset_left = 384.0
|
||||
offset_right = 495.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
text = "Sound test"
|
||||
@@ -0,0 +1,48 @@
|
||||
[gd_scene format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://song_controls.gd" id="part_script"]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_06rl4"]
|
||||
device = -1
|
||||
alt_pressed = true
|
||||
keycode = 86
|
||||
unicode = 8249
|
||||
|
||||
[sub_resource type="Shortcut" id="Shortcut_a7fvb"]
|
||||
events = [SubResource("InputEventKey_06rl4")]
|
||||
|
||||
[sub_resource type="InputEventKey" id="InputEventKey_7dnqw"]
|
||||
device = -1
|
||||
alt_pressed = true
|
||||
keycode = 67
|
||||
unicode = 231
|
||||
|
||||
[sub_resource type="Shortcut" id="Shortcut_d6fml"]
|
||||
events = [SubResource("InputEventKey_7dnqw")]
|
||||
|
||||
[node name="SongControls" type="Control" unique_id=1640212773]
|
||||
layout_mode = 3
|
||||
offset_right = 303.0
|
||||
offset_bottom = 31.0
|
||||
mouse_filter = 2
|
||||
script = ExtResource("part_script")
|
||||
|
||||
[node name="ShowAnswerButton" type="Button" parent="." unique_id=415388039]
|
||||
layout_mode = 0
|
||||
offset_right = 111.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
action_mode = 0
|
||||
shortcut = SubResource("Shortcut_a7fvb")
|
||||
text = "Show answer"
|
||||
|
||||
[node name="NextButton" type="Button" parent="." unique_id=1744703488]
|
||||
layout_mode = 0
|
||||
offset_left = 128.0
|
||||
offset_right = 303.0
|
||||
offset_bottom = 31.0
|
||||
focus_mode = 0
|
||||
disabled = true
|
||||
action_mode = 0
|
||||
shortcut = SubResource("Shortcut_d6fml")
|
||||
text = "Randomize new track"
|
||||
@@ -0,0 +1,10 @@
|
||||
class_name NowPlaying
|
||||
extends VBoxContainer
|
||||
## The soundtrack and song that are playing, in large text at the top of the quiz.
|
||||
|
||||
|
||||
## Shows [param soundtrack_title] and [param song_title]. The playlist hides them as
|
||||
## question marks until the answer is shown.
|
||||
func show_song(soundtrack_title: String, song_title: String) -> void:
|
||||
$SoundtrackLabel.text = soundtrack_title
|
||||
$SongLabel.text = song_title
|
||||
@@ -0,0 +1 @@
|
||||
uid://beoi75d4u568h
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
class_name QuizToolbar
|
||||
extends Control
|
||||
## The row of quiz buttons under the top bar: reset playlist, reset points, settings
|
||||
## and sound test.
|
||||
|
||||
signal reset_playlist_pressed
|
||||
signal reset_points_pressed
|
||||
signal settings_pressed
|
||||
signal sound_test_pressed
|
||||
|
||||
@onready var reset_playlist_button: Button = $ResetPlaylistButton
|
||||
@onready var sound_test_button: Button = $SoundTestButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
reset_playlist_button.pressed.connect(reset_playlist_pressed.emit)
|
||||
$ResetPointsButton.pressed.connect(reset_points_pressed.emit)
|
||||
$SettingsButton.pressed.connect(settings_pressed.emit)
|
||||
sound_test_button.pressed.connect(sound_test_pressed.emit)
|
||||
|
||||
|
||||
## Disables the buttons that use the song list, e.g. while the server syncs it.
|
||||
func set_locked(locked: bool) -> void:
|
||||
reset_playlist_button.disabled = locked
|
||||
sound_test_button.disabled = locked
|
||||
@@ -0,0 +1 @@
|
||||
uid://dmsy36s1ht7x5
|
||||
@@ -0,0 +1,27 @@
|
||||
class_name SongControls
|
||||
extends Control
|
||||
## The buttons for the song that is playing: show the answer, and go to the next song.
|
||||
|
||||
signal show_answer_pressed
|
||||
signal next_pressed
|
||||
|
||||
@onready var show_answer_button: Button = $ShowAnswerButton
|
||||
@onready var next_button: Button = $NextButton
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
show_answer_button.pressed.connect(show_answer_pressed.emit)
|
||||
next_button.pressed.connect(next_pressed.emit)
|
||||
|
||||
|
||||
## Enables Next while there is a downloaded song to play next.
|
||||
func set_next_enabled(enabled: bool) -> void:
|
||||
next_button.disabled = !enabled
|
||||
|
||||
|
||||
## Disables both buttons, e.g. while the server syncs the song list. Unlocking enables
|
||||
## Show answer again; Next comes back when the next song has been downloaded.
|
||||
func set_locked(locked: bool) -> void:
|
||||
show_answer_button.disabled = locked
|
||||
if locked:
|
||||
next_button.disabled = true
|
||||
@@ -0,0 +1 @@
|
||||
uid://d6nevh66yaw1
|
||||
+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)
|
||||
@@ -0,0 +1 @@
|
||||
uid://dwqirg7x7mmj6
|
||||
@@ -70,7 +70,7 @@ func _press(button_path: String) -> void:
|
||||
|
||||
## Presses Next and waits until the first song is playing.
|
||||
func _play_first_song() -> void:
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
|
||||
|
||||
@@ -12,16 +12,24 @@ const BASELINE_PATH: String = "res://tests/data/layout_baseline.json"
|
||||
|
||||
## Nodes that moved from the main window into the Quiz scene, by their old name.
|
||||
const QUIZ_NODES: Array[String] = [
|
||||
"Open", "FileDialog", "MusicListPanel", "VBoxContainer",
|
||||
"MusicPlayer", "ResetPlaylistButton", "ResetPointsButton", "SettingsButton",
|
||||
"SoundTestButton", "ShowAnswerButton", "NextButton", "RepeatSongCheckButton",
|
||||
"DebugLabel", "SettingsWindow", "NewCharacterSelect", "WinnerWindow", "Log",
|
||||
"Open", "FileDialog", "MusicListPanel", "DebugLabel", "SettingsWindow",
|
||||
"NewCharacterSelect", "WinnerWindow", "Log",
|
||||
]
|
||||
|
||||
## Nodes that moved into the Quiz scene and were renamed there: old name to new name.
|
||||
## Nodes that moved into the Quiz scene under another path: old name to new path in
|
||||
## the quiz.
|
||||
const RENAMED_QUIZ_NODES: Dictionary = {
|
||||
"Players": "PlayersPanel",
|
||||
"ScrollContainer": "InspirationList",
|
||||
"VBoxContainer": "NowPlaying",
|
||||
"MusicPlayer": "MusicPlayer/PlayerBar",
|
||||
"RepeatSongCheckButton": "MusicPlayer/RepeatSongCheckButton",
|
||||
"ResetPlaylistButton": "QuizToolbar/ResetPlaylistButton",
|
||||
"ResetPointsButton": "QuizToolbar/ResetPointsButton",
|
||||
"SettingsButton": "QuizToolbar/SettingsButton",
|
||||
"SoundTestButton": "QuizToolbar/SoundTestButton",
|
||||
"ShowAnswerButton": "SongControls/ShowAnswerButton",
|
||||
"NextButton": "SongControls/NextButton",
|
||||
}
|
||||
|
||||
## Nodes that moved from the main window into the TopBar scene, by their old name.
|
||||
|
||||
@@ -7,7 +7,7 @@ func test_startup_loads_soundtracks_and_preloads_a_song() -> void:
|
||||
assert_int(_server.count("/music/all")).is_equal(1)
|
||||
assert_array(_server.requested_paths).contains(["/music/rand", "/music/addQue", "/music/info"])
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
assert_bool((_quiz.get_node("NextButton") as Button).disabled).is_false()
|
||||
assert_bool((_quiz.get_node("SongControls/NextButton") as Button).disabled).is_false()
|
||||
|
||||
|
||||
func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
@@ -15,7 +15,7 @@ func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
_server.respond_bytes(
|
||||
"/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
assert_int(_server.count("/music/rand/low")).is_equal(1)
|
||||
|
||||
@@ -23,7 +23,7 @@ func test_low_played_mode_fetches_from_low_played_endpoint() -> void:
|
||||
func test_next_plays_preloaded_song_and_fetches_another() -> void:
|
||||
_next_song_is(SONG_INFO[1])
|
||||
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
||||
@@ -33,23 +33,23 @@ func test_next_plays_preloaded_song_and_fetches_another() -> void:
|
||||
|
||||
|
||||
func test_title_is_hidden_until_answer_is_shown() -> void:
|
||||
var soundtrack_label: Label = _quiz.get_node("VBoxContainer/SoundtrackLabel")
|
||||
_press("NextButton")
|
||||
var soundtrack_label: Label = _quiz.get_node("NowPlaying/SoundtrackLabel")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
assert_str(soundtrack_label.text).is_equal("????????")
|
||||
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_str(soundtrack_label.text).is_equal("Chrono Trigger")
|
||||
assert_int(_server.count("/music/played?song=0")).is_equal(1)
|
||||
|
||||
|
||||
func test_reset_playlist_clears_server_and_preloads_again() -> void:
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
_press("ResetPlaylistButton")
|
||||
_press("QuizToolbar/ResetPlaylistButton")
|
||||
|
||||
assert_int(_server.count("/music/reset")).is_equal(1)
|
||||
assert_int(Playlist.currently_playing_song).is_equal(-1)
|
||||
@@ -61,7 +61,7 @@ func test_reset_points_sets_all_scores_to_zero() -> void:
|
||||
_add_player("Crono").add_point()
|
||||
_add_player("Marle").add_point()
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_int(Settings.player_array[0].player_score).is_equal(0)
|
||||
assert_int(Settings.player_array[1].player_score).is_equal(0)
|
||||
@@ -81,13 +81,13 @@ func test_cannot_add_player_without_name() -> void:
|
||||
|
||||
|
||||
func test_failed_song_download_is_retried_until_the_server_answers() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
var songs_before: int = Playlist.song_object_array.size()
|
||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||
_server.respond_bytes("/music/rand", PackedByteArray(), 503)
|
||||
var rand_requests_before: int = _server.count("/music/rand")
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(200)
|
||||
|
||||
assert_int(_server.count("/music/rand") - rand_requests_before).is_greater(1)
|
||||
@@ -102,13 +102,13 @@ func test_failed_song_download_is_retried_until_the_server_answers() -> void:
|
||||
|
||||
|
||||
func test_failed_song_info_retries_only_that_step() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
var songs_before: int = Playlist.song_object_array.size()
|
||||
_server.respond_bytes("/music/info", PackedByteArray(), 503)
|
||||
var rand_before: int = _server.count("/music/rand")
|
||||
var queue_before: int = _server.count("/music/addQue")
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(200)
|
||||
_next_song_is(SONG_INFO[1])
|
||||
await await_millis(200)
|
||||
@@ -124,7 +124,7 @@ func test_failed_song_info_retries_only_that_step() -> void:
|
||||
func test_preloads_as_many_songs_as_the_cache_setting() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(3)
|
||||
assert_bool(Playlist.is_song_downloading).is_false()
|
||||
@@ -132,7 +132,7 @@ func test_preloads_as_many_songs_as_the_cache_setting() -> void:
|
||||
|
||||
func test_playing_a_song_tops_the_cache_up_again() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
|
||||
await _play_first_song()
|
||||
|
||||
@@ -141,13 +141,13 @@ func test_playing_a_song_tops_the_cache_up_again() -> void:
|
||||
|
||||
|
||||
func test_cache_keeps_filling_after_a_failed_download() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||
# One more download works, then the server stops answering
|
||||
_server.fail_after("/music/rand", 1)
|
||||
|
||||
_quiz.fetch_song()
|
||||
_quiz.song_loader.fetch_song()
|
||||
await await_millis(150)
|
||||
|
||||
assert_int(Playlist.get_preloaded_songs()).is_equal(2)
|
||||
@@ -161,7 +161,7 @@ func test_cache_keeps_filling_after_a_failed_download() -> void:
|
||||
|
||||
|
||||
func _open_settings() -> void:
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
|
||||
|
||||
func _close_settings() -> void:
|
||||
@@ -217,14 +217,14 @@ func test_closing_settings_with_full_cache_downloads_nothing() -> void:
|
||||
|
||||
|
||||
func test_show_answer_before_first_song_does_not_reveal_next_song() -> void:
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_bool(Playlist.song_object_array[0].is_answered).is_false()
|
||||
assert_int(_server.count("/music/played?song=-1")).is_equal(0)
|
||||
|
||||
await _play_first_song()
|
||||
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_equal("????????")
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ func test_next_plays_the_preloaded_song_after_a_slow_song_list() -> void:
|
||||
|
||||
|
||||
func test_failed_song_list_is_retried_before_preloading() -> void:
|
||||
_quiz.song_fetch_retry_seconds = 0.05
|
||||
_quiz.song_loader.retry_seconds = 0.05
|
||||
_server.respond_json("/music/list", [], 503)
|
||||
_server.release("/music/list")
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
extends GdUnitTestSuite
|
||||
## The music player scene: the player bar and the auto repeat switch under it.
|
||||
|
||||
var _snapshot: AutoloadSnapshot
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _player: MusicPlayer
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_snapshot = AutoloadSnapshot.take([Settings])
|
||||
Settings.auto_repeat_song = true
|
||||
_runner = scene_runner("res://MusicPlayer.tscn")
|
||||
_player = _runner.scene()
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
_snapshot.restore()
|
||||
|
||||
|
||||
func _click(control: Control) -> void:
|
||||
_runner.set_mouse_position(_player.get_viewport().get_final_transform()
|
||||
* control.get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_auto_repeat_starts_on() -> void:
|
||||
assert_bool(_player.auto_repeat_button.button_pressed).is_true()
|
||||
|
||||
|
||||
func test_clicking_auto_repeat_turns_it_off_and_on() -> void:
|
||||
await _click(_player.auto_repeat_button)
|
||||
assert_bool(Settings.auto_repeat_song).is_false()
|
||||
assert_bool(_player.auto_repeat_button.button_pressed).is_false()
|
||||
|
||||
await _click(_player.auto_repeat_button)
|
||||
assert_bool(Settings.auto_repeat_song).is_true()
|
||||
|
||||
|
||||
func test_auto_repeat_is_under_the_player_bar() -> void:
|
||||
await _runner.simulate_frames(1)
|
||||
var bar: Rect2 = (_player.get_node("PlayerBar") as Control).get_global_rect()
|
||||
var repeat: Rect2 = _player.auto_repeat_button.get_global_rect()
|
||||
|
||||
assert_float(repeat.position.y).is_greater_equal(bar.end.y)
|
||||
assert_bool(_player.get_global_rect().encloses(repeat)).is_true()
|
||||
|
||||
|
||||
func test_empty_space_lets_clicks_through() -> void:
|
||||
assert_int(_player.mouse_filter).is_equal(Control.MOUSE_FILTER_IGNORE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ck3ti57dgce3w
|
||||
@@ -0,0 +1,34 @@
|
||||
extends GdUnitTestSuite
|
||||
## The soundtrack and song shown at the top of the quiz.
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _now_playing: NowPlaying
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://NowPlaying.tscn")
|
||||
_now_playing = _runner.scene()
|
||||
|
||||
|
||||
func _label(label_name: String) -> Label:
|
||||
return _now_playing.get_node(label_name)
|
||||
|
||||
|
||||
func test_starts_empty() -> void:
|
||||
assert_str(_label("SoundtrackLabel").text).is_empty()
|
||||
assert_str(_label("SongLabel").text).is_empty()
|
||||
|
||||
|
||||
func test_show_song_shows_soundtrack_and_song() -> void:
|
||||
_now_playing.show_song("Chrono Trigger", "Corridors of Time")
|
||||
|
||||
assert_str(_label("SoundtrackLabel").text).is_equal("Chrono Trigger")
|
||||
assert_str(_label("SongLabel").text).is_equal("Corridors of Time")
|
||||
|
||||
|
||||
func test_soundtrack_is_above_song() -> void:
|
||||
_now_playing.show_song("Chrono Trigger", "Corridors of Time")
|
||||
await _runner.simulate_frames(1)
|
||||
|
||||
assert_float(_label("SoundtrackLabel").get_global_rect().end.y) \
|
||||
.is_less_equal(_label("SongLabel").get_global_rect().position.y)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cidytlxgrmlk0
|
||||
@@ -80,7 +80,7 @@ func test_click_inside_popup_keeps_it_open() -> void:
|
||||
|
||||
func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||
var settings: PopupWindow = _popup("SettingsWindow")
|
||||
var reset_button: Button = _quiz.get_node("ResetPlaylistButton")
|
||||
var reset_button: Button = _quiz.get_node("QuizToolbar/ResetPlaylistButton")
|
||||
settings.open()
|
||||
await _runner.simulate_frames(1)
|
||||
assert_bool(settings.panel.get_global_rect().intersects(reset_button.get_global_rect())) \
|
||||
@@ -93,7 +93,7 @@ func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||
|
||||
|
||||
func test_button_works_again_after_popup_closed() -> void:
|
||||
var reset_button: Button = _quiz.get_node("ResetPlaylistButton")
|
||||
var reset_button: Button = _quiz.get_node("QuizToolbar/ResetPlaylistButton")
|
||||
|
||||
await _click_at(reset_button.get_global_rect().get_center())
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
extends GdUnitTestSuite
|
||||
## The row of quiz buttons: each button reports its press, and locking disables the
|
||||
## buttons that use the song list.
|
||||
|
||||
const BUTTON_SIGNALS: Dictionary = {
|
||||
"ResetPlaylistButton": "reset_playlist_pressed",
|
||||
"ResetPointsButton": "reset_points_pressed",
|
||||
"SettingsButton": "settings_pressed",
|
||||
"SoundTestButton": "sound_test_pressed",
|
||||
}
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _toolbar: QuizToolbar
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://QuizToolbar.tscn")
|
||||
_toolbar = _runner.scene()
|
||||
|
||||
|
||||
func _button(button_name: String) -> Button:
|
||||
return _toolbar.get_node(button_name)
|
||||
|
||||
|
||||
func _click(button_name: String) -> void:
|
||||
_runner.set_mouse_position(_toolbar.get_viewport().get_final_transform()
|
||||
* _button(button_name).get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_clicking_each_button_reports_it() -> void:
|
||||
for button_name: String in BUTTON_SIGNALS:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_toolbar))
|
||||
|
||||
await _click(button_name)
|
||||
|
||||
await signals.override_failure_message(button_name + " not reported") \
|
||||
.is_emitted(BUTTON_SIGNALS[button_name])
|
||||
|
||||
|
||||
func test_buttons_are_in_order_left_to_right() -> void:
|
||||
var lefts: Array = ["ResetPlaylistButton", "ResetPointsButton", "SettingsButton",
|
||||
"SoundTestButton"].map(func(n: String) -> float: return _button(n).position.x)
|
||||
|
||||
for i: int in lefts.size() - 1:
|
||||
assert_float(lefts[i]).is_less(lefts[i + 1])
|
||||
|
||||
|
||||
func test_locking_disables_only_buttons_that_use_the_song_list() -> void:
|
||||
_toolbar.set_locked(true)
|
||||
|
||||
assert_bool(_button("ResetPlaylistButton").disabled).is_true()
|
||||
assert_bool(_button("SoundTestButton").disabled).is_true()
|
||||
assert_bool(_button("ResetPointsButton").disabled).is_false()
|
||||
assert_bool(_button("SettingsButton").disabled).is_false()
|
||||
|
||||
|
||||
func test_unlocking_enables_them_again() -> void:
|
||||
_toolbar.set_locked(true)
|
||||
|
||||
_toolbar.set_locked(false)
|
||||
|
||||
assert_bool(_button("ResetPlaylistButton").disabled).is_false()
|
||||
assert_bool(_button("SoundTestButton").disabled).is_false()
|
||||
|
||||
|
||||
func test_clicks_between_buttons_go_through() -> void:
|
||||
assert_int(_toolbar.mouse_filter).is_equal(Control.MOUSE_FILTER_IGNORE)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ecsdudhpw8oi
|
||||
@@ -51,11 +51,21 @@ func test_top_bar_is_drawn_below_the_quiz() -> void:
|
||||
|
||||
|
||||
func test_quiz_parts_are_their_own_scenes() -> void:
|
||||
for node_name: String in ["MusicListPanel", "PlayersPanel", "InspirationList"]:
|
||||
for node_name: String in ["MusicListPanel", "PlayersPanel", "InspirationList",
|
||||
"NowPlaying", "QuizToolbar", "SongControls", "MusicPlayer"]:
|
||||
assert_str(_quiz.get_node(node_name).scene_file_path) \
|
||||
.is_equal("res://%s.tscn" % node_name)
|
||||
|
||||
|
||||
func test_quiz_downloads_songs_with_a_song_loader() -> void:
|
||||
assert_object(_quiz.song_loader).is_instanceof(SongLoader)
|
||||
|
||||
|
||||
func test_auto_repeat_is_part_of_the_music_player() -> void:
|
||||
assert_object(_quiz.get_node("MusicPlayer/RepeatSongCheckButton")).is_instanceof(CheckButton)
|
||||
assert_object(_quiz.get_node_or_null("RepeatSongCheckButton")).is_null()
|
||||
|
||||
|
||||
func test_top_bar_holds_only_title_and_buttons() -> void:
|
||||
assert_array(_children(_window.get_node("TopBar"))) \
|
||||
.contains_exactly_in_any_order(TOP_BAR_CHILDREN)
|
||||
@@ -83,22 +93,22 @@ func test_clicking_each_top_bar_button_opens_its_popup() -> void:
|
||||
|
||||
|
||||
func test_clicking_quiz_buttons_plays_and_shows_answer() -> void:
|
||||
await _click_at(_center(_quiz.get_node("NextButton")))
|
||||
await _click_at(_center(_quiz.get_node("SongControls/NextButton")))
|
||||
await _runner.simulate_frames(2)
|
||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_not_equal("Chrono Trigger")
|
||||
|
||||
await _click_at(_center(_quiz.get_node("ShowAnswerButton")))
|
||||
await _click_at(_center(_quiz.get_node("SongControls/ShowAnswerButton")))
|
||||
|
||||
assert_str((_quiz.get_node("VBoxContainer/SoundtrackLabel") as Label).text) \
|
||||
assert_str((_quiz.get_node("NowPlaying/SoundtrackLabel") as Label).text) \
|
||||
.is_equal("Chrono Trigger")
|
||||
|
||||
|
||||
func test_clicking_a_song_in_the_music_list_plays_it() -> void:
|
||||
_next_song_is(SONG_INFO[1])
|
||||
await _play_first_song()
|
||||
_press("NextButton")
|
||||
_press("SongControls/NextButton")
|
||||
# Changing song waits a moment for the old one to stop
|
||||
await get_tree().create_timer(0.7).timeout
|
||||
assert_int(Playlist.currently_playing_song).is_equal(1)
|
||||
@@ -137,6 +147,30 @@ func test_character_button_in_the_player_list_picks_a_new_character() -> void:
|
||||
assert_object(crono.character).is_same(texture)
|
||||
|
||||
|
||||
func test_sound_test_button_fetches_the_sound_test_song() -> void:
|
||||
_server.respond_bytes("/music/soundTest", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
await _click_at(_center(_quiz.get_node("QuizToolbar/SoundTestButton")))
|
||||
|
||||
assert_int(_server.count("/music/soundTest")).is_equal(1)
|
||||
|
||||
|
||||
func test_loaded_song_list_shows_in_the_music_list() -> void:
|
||||
# No new song finishes downloading, so only loading the list can show the songs
|
||||
_server.hold("/music/rand")
|
||||
_server.respond_json("/music/list", [
|
||||
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
||||
{"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"},
|
||||
])
|
||||
Playlist.is_song_downloading = false
|
||||
|
||||
_quiz.song_loader.load_song_list()
|
||||
|
||||
var rows: Array[Node] = _quiz.get_node("MusicListPanel/ScrollContainer/MusicList").get_children()
|
||||
assert_array(rows.map(func(row: SongListObject) -> int: return row.song_object.song_number)) \
|
||||
.contains_exactly([0, 1])
|
||||
|
||||
|
||||
func test_quiz_popup_backdrop_covers_the_top_bar() -> void:
|
||||
var settings: PopupWindow = _quiz.get_node("SettingsWindow")
|
||||
settings.open()
|
||||
@@ -169,8 +203,8 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
_top_bar_button("SyncButton").pressed.emit()
|
||||
sync_window.sync_timer.stop()
|
||||
|
||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
||||
"NextButton"]:
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||
.override_failure_message(button_name + " not disabled").is_true()
|
||||
assert_bool(_top_bar_button("SyncButton").disabled).is_false()
|
||||
@@ -180,8 +214,8 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
||||
sync_window._on_sync_timeout()
|
||||
await _runner.simulate_frames(2)
|
||||
|
||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
||||
"NextButton"]:
|
||||
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||
"SongControls/NextButton"]:
|
||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||
.override_failure_message(button_name + " still disabled").is_false()
|
||||
# The search list in the main window and the quiz playlist are both reloaded
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
extends GdUnitTestSuite
|
||||
## Show answer and Next: each reports its press, also from its keyboard shortcut, and
|
||||
## Next is only enabled while a song is ready.
|
||||
|
||||
var _runner: GdUnitSceneRunner
|
||||
var _controls: SongControls
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_runner = scene_runner("res://SongControls.tscn")
|
||||
_controls = _runner.scene()
|
||||
|
||||
|
||||
func _click(button: Button) -> void:
|
||||
_runner.set_mouse_position(_controls.get_viewport().get_final_transform()
|
||||
* button.get_global_rect().get_center())
|
||||
await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func _press_keys(keys: Array[Key]) -> void:
|
||||
for key: Key in keys:
|
||||
_runner.simulate_key_press(key)
|
||||
await _runner.await_input_processed()
|
||||
keys.reverse()
|
||||
for key: Key in keys:
|
||||
_runner.simulate_key_release(key)
|
||||
await _runner.await_input_processed()
|
||||
|
||||
|
||||
func test_next_starts_disabled() -> void:
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
|
||||
|
||||
func test_clicking_show_answer_reports_it() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.show_answer_button)
|
||||
|
||||
await signals.is_emitted("show_answer_pressed")
|
||||
|
||||
|
||||
func test_clicking_next_reports_it_when_enabled() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.next_button)
|
||||
|
||||
await signals.is_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_clicking_disabled_next_does_nothing() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _click(_controls.next_button)
|
||||
|
||||
await signals.wait_until(200).is_not_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_alt_v_shows_answer_and_alt_c_plays_next() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_controls))
|
||||
|
||||
await _press_keys([KEY_ALT, KEY_V])
|
||||
await signals.is_emitted("show_answer_pressed")
|
||||
await _press_keys([KEY_ALT, KEY_C])
|
||||
await signals.is_emitted("next_pressed")
|
||||
|
||||
|
||||
func test_locking_disables_both() -> void:
|
||||
_controls.set_next_enabled(true)
|
||||
|
||||
_controls.set_locked(true)
|
||||
|
||||
assert_bool(_controls.show_answer_button.disabled).is_true()
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
|
||||
|
||||
func test_unlocking_enables_show_answer_but_waits_for_a_song_for_next() -> void:
|
||||
_controls.set_locked(true)
|
||||
|
||||
_controls.set_locked(false)
|
||||
|
||||
assert_bool(_controls.show_answer_button.disabled).is_false()
|
||||
assert_bool(_controls.next_button.disabled).is_true()
|
||||
@@ -0,0 +1 @@
|
||||
uid://c43ii6v73reks
|
||||
@@ -0,0 +1,122 @@
|
||||
extends GdUnitTestSuite
|
||||
## Downloading songs into the Playlist ahead of time, against a fake server.
|
||||
|
||||
const SONG_INFO: Dictionary = {"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"}
|
||||
|
||||
var _snapshot: AutoloadSnapshot
|
||||
var _server: FakeHttpTransport
|
||||
var _loader: SongLoader
|
||||
|
||||
|
||||
func before_test() -> void:
|
||||
_snapshot = AutoloadSnapshot.take([Settings, Playlist])
|
||||
Playlist.reset_playlist()
|
||||
Playlist.is_song_downloading = false
|
||||
Playlist.number_of_tracks_to_preload = 1
|
||||
Settings.use_low_played_mode = false
|
||||
_server = FakeHttpTransport.new().install()
|
||||
_server.respond_json("/music/list", [])
|
||||
_server.respond_bytes("/music/rand", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
_server.respond_bytes("/music/addQue", PackedByteArray())
|
||||
_server.respond_json("/music/info", SONG_INFO)
|
||||
_loader = auto_free(SongLoader.new())
|
||||
add_child(_loader)
|
||||
|
||||
|
||||
func after_test() -> void:
|
||||
_server.uninstall()
|
||||
_snapshot.restore()
|
||||
|
||||
|
||||
func test_load_song_list_adds_songs_already_played_on_the_server() -> void:
|
||||
_server.respond_json("/music/list", [
|
||||
{"SongNo": 0, "Soundtrack": "Chrono Trigger", "Song": "Corridors of Time"},
|
||||
])
|
||||
_server.respond_json("/music/info", {"SongNo": 1, "Soundtrack": "Final Fantasy VI", "Song": "Dancing Mad"})
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_loader))
|
||||
|
||||
_loader.load_song_list()
|
||||
|
||||
await signals.is_emitted("song_list_loaded")
|
||||
var first: SongObject = Playlist.song_object_array[0]
|
||||
assert_str(first.soundtrack_title).is_equal("Chrono Trigger")
|
||||
assert_bool(first.has_played).is_true()
|
||||
assert_bool(first.is_answered).is_true()
|
||||
|
||||
|
||||
func test_load_song_list_then_preloads_a_new_song() -> void:
|
||||
_loader.load_song_list()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
|
||||
|
||||
func test_fetch_song_downloads_queues_and_adds_the_song() -> void:
|
||||
var signals: GdUnitSignalAssert = assert_signal(monitor_signals(_loader))
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
await signals.is_emitted("song_added")
|
||||
assert_array(_server.requested_paths).contains_exactly(["/music/rand", "/music/addQue", "/music/info"])
|
||||
var song: SongObject = Playlist.song_object_array[0]
|
||||
assert_str(song.song_title).is_equal("Corridors of Time")
|
||||
assert_object(song.song).is_not_null()
|
||||
assert_bool(Playlist.is_song_downloading).is_false()
|
||||
|
||||
|
||||
func test_fetch_song_keeps_going_until_the_cache_is_full() -> void:
|
||||
Playlist.number_of_tracks_to_preload = 3
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(3)
|
||||
assert_int(_server.count("/music/rand")).is_equal(3)
|
||||
|
||||
|
||||
func test_low_played_mode_uses_its_endpoint() -> void:
|
||||
Settings.use_low_played_mode = true
|
||||
_server.respond_bytes("/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
||||
|
||||
_loader.fetch_song()
|
||||
|
||||
assert_int(_server.count("/music/rand/low")).is_equal(1)
|
||||
assert_int(_server.count("/music/rand")).is_equal(0)
|
||||
|
||||
|
||||
func test_fetch_song_if_idle_does_nothing_while_downloading() -> void:
|
||||
Playlist.is_song_downloading = true
|
||||
|
||||
_loader.fetch_song_if_idle()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(0)
|
||||
|
||||
|
||||
func test_fill_cache_does_nothing_when_the_cache_is_full() -> void:
|
||||
_loader.fetch_song()
|
||||
|
||||
_loader.fill_cache()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
|
||||
|
||||
func test_fill_cache_downloads_after_the_cache_size_grows() -> void:
|
||||
_loader.fetch_song()
|
||||
Playlist.number_of_tracks_to_preload = 2
|
||||
|
||||
_loader.fill_cache()
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(2)
|
||||
|
||||
|
||||
func test_failed_step_is_retried_alone() -> void:
|
||||
_loader.retry_seconds = 0.05
|
||||
_server.fail_after("/music/info", 0)
|
||||
|
||||
_loader.fetch_song()
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(0)
|
||||
_server.respond_json("/music/info", SONG_INFO)
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
|
||||
assert_int(_server.count("/music/rand")).is_equal(1)
|
||||
assert_int(_server.count("/music/addQue")).is_equal(1)
|
||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
||||
@@ -0,0 +1 @@
|
||||
uid://caew6u3yi8m4n
|
||||
@@ -24,7 +24,7 @@ func test_winning_turns_statistics_off() -> void:
|
||||
func test_resetting_points_turns_statistics_back_on() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_true()
|
||||
|
||||
@@ -33,7 +33,7 @@ func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void:
|
||||
Settings.add_to_stats = false
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("ResetPointsButton")
|
||||
_press("QuizToolbar/ResetPointsButton")
|
||||
|
||||
assert_bool(Settings.add_to_stats).is_false()
|
||||
|
||||
@@ -41,7 +41,7 @@ func test_statistics_turned_off_by_hand_stay_off_after_reset() -> void:
|
||||
func test_settings_checkbox_shows_statistics_off_after_win() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
|
||||
assert_bool(_stats_checkbox().button_pressed).is_false()
|
||||
|
||||
@@ -50,13 +50,13 @@ func test_songs_after_a_win_are_not_counted() -> void:
|
||||
await _give_point_with_keybind(1)
|
||||
var played_before: int = _server.count("/music/played?song=0")
|
||||
|
||||
_press("ShowAnswerButton")
|
||||
_press("SongControls/ShowAnswerButton")
|
||||
|
||||
assert_int(_server.count("/music/played?song=0")).is_equal(played_before)
|
||||
|
||||
|
||||
func test_winning_score_cannot_go_below_one() -> void:
|
||||
_press("SettingsButton")
|
||||
_press("QuizToolbar/SettingsButton")
|
||||
var lower_button: Button = _quiz.get_node("SettingsWindow").get_node("%LowerButton")
|
||||
|
||||
for i: int in 3:
|
||||
|
||||
Reference in new issue
Block a user