Add working tests, fix bugs, rework popups and automate releases #36
No files matched your search
+15
-6
@@ -1,14 +1,16 @@
|
|||||||
class_name MusicPlayer
|
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 20/1-24: 136
|
||||||
# LOC 12/6-24: 170
|
# LOC 12/6-24: 170
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var play_button: TextureButton = $MusicPlayerContainer/PlayTextureButton
|
var play_button: TextureButton = $PlayerBar/MusicPlayerContainer/PlayTextureButton
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var restart_button: TextureButton = $MusicPlayerContainer/RestartTextureButton
|
var restart_button: TextureButton = $PlayerBar/MusicPlayerContainer/RestartTextureButton
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var audio_player: AudioStreamPlayer = $AudioStreamPlayer
|
var audio_player: AudioStreamPlayer = $AudioStreamPlayer
|
||||||
@@ -20,13 +22,16 @@ var sound_player: AudioStreamPlayer = $AudioSoundPlayer
|
|||||||
var sound_effect_player: AudioStreamPlayer = $AudioSoundEffectPlayer
|
var sound_effect_player: AudioStreamPlayer = $AudioSoundEffectPlayer
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var progress_slider: HSlider = $MusicPlayerContainer/MusicPlayerSlider
|
var progress_slider: HSlider = $PlayerBar/MusicPlayerContainer/MusicPlayerSlider
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var volume_slider: HSlider = $MusicPlayerContainer/VolumeSlider
|
var volume_slider: HSlider = $PlayerBar/MusicPlayerContainer/VolumeSlider
|
||||||
|
|
||||||
@onready
|
@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 play_icon: Texture = preload("res://icons/play_icon_light.svg")
|
||||||
var pause_icon: Texture = preload("res://icons/pause_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)
|
progress_slider.drag_ended.connect(_on_drag_ended)
|
||||||
|
|
||||||
audio_player.finished.connect(_on_finished)
|
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:
|
func _process(_delta: float) -> void:
|
||||||
if audio_player.has_stream_playback() && !is_changing && !audio_player.stream_paused:
|
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"]
|
[sub_resource type="Shortcut" id="Shortcut_i7swq"]
|
||||||
events = [SubResource("InputEventKey_2nvce")]
|
events = [SubResource("InputEventKey_2nvce")]
|
||||||
|
|
||||||
[node name="MusicPlayer" type="PanelContainer"]
|
[node name="MusicPlayer" type="Control"]
|
||||||
anchors_preset = 8
|
layout_mode = 3
|
||||||
anchor_left = 0.5
|
offset_right = 1792.0
|
||||||
anchor_top = 0.5
|
offset_bottom = 71.0
|
||||||
anchor_right = 0.5
|
mouse_filter = 2
|
||||||
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
|
|
||||||
script = ExtResource("1_t24ra")
|
script = ExtResource("1_t24ra")
|
||||||
|
|
||||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||||
@@ -53,11 +45,17 @@ bus = &"music"
|
|||||||
stream = ExtResource("2_xti80")
|
stream = ExtResource("2_xti80")
|
||||||
bus = &"music"
|
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
|
layout_mode = 2
|
||||||
size_flags_vertical = 4
|
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)
|
custom_minimum_size = Vector2(32, 32)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
focus_mode = 0
|
focus_mode = 0
|
||||||
@@ -67,7 +65,7 @@ texture_normal = ExtResource("3_6g308")
|
|||||||
ignore_texture_size = true
|
ignore_texture_size = true
|
||||||
stretch_mode = 0
|
stretch_mode = 0
|
||||||
|
|
||||||
[node name="RestartTextureButton" type="TextureButton" parent="MusicPlayerContainer"]
|
[node name="RestartTextureButton" type="TextureButton" parent="PlayerBar/MusicPlayerContainer"]
|
||||||
custom_minimum_size = Vector2(32, 32)
|
custom_minimum_size = Vector2(32, 32)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
focus_mode = 0
|
focus_mode = 0
|
||||||
@@ -78,17 +76,27 @@ ignore_texture_size = true
|
|||||||
stretch_mode = 0
|
stretch_mode = 0
|
||||||
flip_h = true
|
flip_h = true
|
||||||
|
|
||||||
[node name="MusicPlayerSlider" type="HSlider" parent="MusicPlayerContainer"]
|
[node name="MusicPlayerSlider" type="HSlider" parent="PlayerBar/MusicPlayerContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
size_flags_vertical = 4
|
size_flags_vertical = 4
|
||||||
scrollable = false
|
scrollable = false
|
||||||
|
|
||||||
[node name="MusicTimeLabel" type="Label" parent="MusicPlayerContainer"]
|
[node name="MusicTimeLabel" type="Label" parent="PlayerBar/MusicPlayerContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "0:00 / 0:00"
|
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)
|
custom_minimum_size = Vector2(100, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 4
|
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://MusicListPanel.tscn" id="scene_MusicListPanel"]
|
||||||
[ext_resource type="PackedScene" path="res://PlayersPanel.tscn" id="scene_PlayersPanel"]
|
[ext_resource type="PackedScene" path="res://PlayersPanel.tscn" id="scene_PlayersPanel"]
|
||||||
[ext_resource type="PackedScene" path="res://InspirationList.tscn" id="scene_InspirationList"]
|
[ext_resource type="PackedScene" path="res://InspirationList.tscn" id="scene_InspirationList"]
|
||||||
|
[ext_resource type="PackedScene" path="res://QuizToolbar.tscn" id="scene_QuizToolbar"]
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_qspbu"]
|
[ext_resource type="PackedScene" path="res://SongControls.tscn" id="scene_SongControls"]
|
||||||
font_size = 50
|
[ext_resource type="PackedScene" path="res://NowPlaying.tscn" id="scene_NowPlaying"]
|
||||||
|
[ext_resource type="Script" path="res://song_loader.gd" id="song_loader_script"]
|
||||||
[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")]
|
|
||||||
|
|
||||||
[node name="Quiz" type="Control" unique_id=1146705218]
|
[node name="Quiz" type="Control" unique_id=1146705218]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
@@ -76,40 +56,19 @@ offset_top = 128.0
|
|||||||
offset_right = 1857.0
|
offset_right = 1857.0
|
||||||
offset_bottom = 512.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
|
layout_mode = 0
|
||||||
offset_left = 64.0
|
offset_left = 64.0
|
||||||
offset_top = 64.0
|
offset_top = 64.0
|
||||||
offset_right = 1152.0
|
offset_right = 1152.0
|
||||||
offset_bottom = 384.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")]
|
[node name="MusicPlayer" parent="." unique_id=1990459832 instance=ExtResource("5_emn36")]
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
anchors_preset = 0
|
offset_left = 64.0
|
||||||
anchor_left = 0.0
|
|
||||||
anchor_top = 0.0
|
|
||||||
anchor_right = 0.0
|
|
||||||
anchor_bottom = 0.0
|
|
||||||
offset_left = 65.0
|
|
||||||
offset_top = 992.0
|
offset_top = 992.0
|
||||||
offset_right = 1856.0
|
offset_right = 1856.0
|
||||||
offset_bottom = 1024.0
|
offset_bottom = 1063.0
|
||||||
grow_horizontal = 1
|
|
||||||
grow_vertical = 1
|
|
||||||
|
|
||||||
[node name="PlayersPanel" parent="." unique_id=1708375945 instance=ExtResource("scene_PlayersPanel")]
|
[node name="PlayersPanel" parent="." unique_id=1708375945 instance=ExtResource("scene_PlayersPanel")]
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
@@ -118,68 +77,19 @@ offset_top = 576.0
|
|||||||
offset_right = 1857.0
|
offset_right = 1857.0
|
||||||
offset_bottom = 977.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
|
layout_mode = 0
|
||||||
offset_left = 1360.0
|
offset_left = 1360.0
|
||||||
offset_top = 64.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_right = 1855.0
|
||||||
offset_bottom = 95.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
|
layout_mode = 0
|
||||||
offset_left = 65.0
|
offset_left = 65.0
|
||||||
offset_top = 944.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_right = 368.0
|
||||||
offset_bottom = 975.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")]
|
[node name="SettingsWindow" parent="." unique_id=1323246978 instance=ExtResource("11_k62u5")]
|
||||||
visible = false
|
visible = false
|
||||||
@@ -207,17 +117,6 @@ offset_top = 153.0
|
|||||||
offset_right = 720.0
|
offset_right = 720.0
|
||||||
offset_bottom = 153.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]
|
[node name="DebugLabel" type="Label" parent="." unique_id=1959221257]
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
@@ -240,4 +139,7 @@ offset_top = 132.0
|
|||||||
offset_right = 1262.0
|
offset_right = 1262.0
|
||||||
offset_bottom = 832.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"]
|
[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
|
var inspiration_list: InspirationList = $InspirationList
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var soundtrack_label: Label = $VBoxContainer/SoundtrackLabel
|
var now_playing: NowPlaying = $NowPlaying
|
||||||
|
|
||||||
@onready
|
|
||||||
var song_label: Label = $VBoxContainer/SongLabel
|
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var players_panel: PlayersPanel = $PlayersPanel
|
var players_panel: PlayersPanel = $PlayersPanel
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var reset_playlist_button: Button = $ResetPlaylistButton
|
var toolbar: QuizToolbar = $QuizToolbar
|
||||||
|
|
||||||
@onready
|
|
||||||
var reset_points_button: Button = $ResetPointsButton
|
|
||||||
|
|
||||||
@onready
|
|
||||||
var sound_test_button: Button = $SoundTestButton
|
|
||||||
|
|
||||||
@onready
|
|
||||||
var settings_button: Button = $SettingsButton
|
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var settings_window: Control = $SettingsWindow
|
var settings_window: Control = $SettingsWindow
|
||||||
@@ -48,10 +36,10 @@ var settings_window: Control = $SettingsWindow
|
|||||||
var winner_window: Control = %WinnerWindow
|
var winner_window: Control = %WinnerWindow
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var show_answer_button: Button = $ShowAnswerButton
|
var song_controls: SongControls = $SongControls
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var next_button: Button = $NextButton
|
var song_loader: SongLoader = $SongLoader
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var music_list_panel: MusicListPanel = $MusicListPanel
|
var music_list_panel: MusicListPanel = $MusicListPanel
|
||||||
@@ -60,10 +48,7 @@ var music_list_panel: MusicListPanel = $MusicListPanel
|
|||||||
var new_character_select: Control = %NewCharacterSelect
|
var new_character_select: Control = %NewCharacterSelect
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var auto_repeat_song_button: CheckButton = $RepeatSongCheckButton
|
var music_player_container: MusicPlayer = $MusicPlayer
|
||||||
|
|
||||||
@onready
|
|
||||||
var music_player_container: PanelContainer = $MusicPlayer
|
|
||||||
|
|
||||||
@onready
|
@onready
|
||||||
var log_window: Control = %Log
|
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.
|
## Dims the window behind an open popup and keeps clicks from reaching the buttons under it.
|
||||||
var popup_backdrop: PopupBackdrop
|
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:
|
func _ready() -> void:
|
||||||
popup_backdrop = PopupBackdrop.add_to(self, _popups())
|
popup_backdrop = PopupBackdrop.add_to(self, _popups())
|
||||||
@@ -92,12 +74,14 @@ func _ready() -> void:
|
|||||||
Settings.is_debug = true
|
Settings.is_debug = true
|
||||||
settings_window.set_winning_score(5)
|
settings_window.set_winning_score(5)
|
||||||
settings_window.set_selected_server(4)
|
settings_window.set_selected_server(4)
|
||||||
next_button.pressed.connect(play_next_song)
|
song_controls.next_pressed.connect(play_next_song)
|
||||||
show_answer_button.pressed.connect(show_answer_pressed)
|
song_controls.show_answer_pressed.connect(show_answer_pressed)
|
||||||
sound_test_button.pressed.connect(music_player_container.get_sound_test_song)
|
toolbar.sound_test_pressed.connect(music_player_container.get_sound_test_song)
|
||||||
settings_button.pressed.connect(show_settings)
|
toolbar.settings_pressed.connect(show_settings)
|
||||||
reset_playlist_button.pressed.connect(reset_playlist)
|
toolbar.reset_playlist_pressed.connect(reset_playlist)
|
||||||
reset_points_button.pressed.connect(reset_points)
|
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)
|
new_character_select.connect("new_new_character_selected", _on_new_character_selected)
|
||||||
music_list_panel.song_clicked.connect(song_object_clicked)
|
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)
|
settings_window.visibility_changed.connect(_on_settings_window_visibility_changed)
|
||||||
|
|
||||||
open_button.pressed.connect(open)
|
open_button.pressed.connect(open)
|
||||||
auto_repeat_song_button.pressed.connect(repeat_song)
|
|
||||||
|
|
||||||
inspiration_list.load_from_server()
|
inspiration_list.load_from_server()
|
||||||
fetch_song_list_at_start()
|
song_loader.load_song_list()
|
||||||
new_character_select.load_characters()
|
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.
|
## Disables the buttons that use the song list while the server syncs it.
|
||||||
func lock_for_sync() -> void:
|
func lock_for_sync() -> void:
|
||||||
sound_test_button.disabled = true
|
toolbar.set_locked(true)
|
||||||
reset_playlist_button.disabled = true
|
song_controls.set_locked(true)
|
||||||
show_answer_button.disabled = true
|
|
||||||
next_button.disabled = true
|
|
||||||
|
|
||||||
|
|
||||||
## Reloads from the server after a sync and starts a new game.
|
## Reloads from the server after a sync and starts a new game.
|
||||||
func on_sync_finished() -> void:
|
func on_sync_finished() -> void:
|
||||||
refresh_from_server()
|
refresh_from_server()
|
||||||
sound_test_button.disabled = false
|
toolbar.set_locked(false)
|
||||||
reset_playlist_button.disabled = false
|
song_controls.set_locked(false)
|
||||||
show_answer_button.disabled = false
|
|
||||||
reset_points()
|
reset_points()
|
||||||
|
|
||||||
|
|
||||||
@@ -170,41 +150,12 @@ func _on_server_changed() -> void:
|
|||||||
server_changed.emit()
|
server_changed.emit()
|
||||||
|
|
||||||
|
|
||||||
func repeat_song() -> void:
|
|
||||||
Settings.auto_repeat_song = !Settings.auto_repeat_song
|
|
||||||
|
|
||||||
|
|
||||||
func show_answer_pressed() -> void:
|
func show_answer_pressed() -> void:
|
||||||
print("show_answer_pressed")
|
print("show_answer_pressed")
|
||||||
Playlist.song_is_answered()
|
Playlist.song_is_answered()
|
||||||
update_song_list()
|
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:
|
func play_next_song() -> void:
|
||||||
print("play_next_song ", Playlist.latest_played_song)
|
print("play_next_song ", Playlist.latest_played_song)
|
||||||
if Playlist.first_song_played:
|
if Playlist.first_song_played:
|
||||||
@@ -212,9 +163,8 @@ func play_next_song() -> void:
|
|||||||
Playlist.first_song_played = true
|
Playlist.first_song_played = true
|
||||||
music_player_container.play_song_object(Playlist.latest_played_song)
|
music_player_container.play_song_object(Playlist.latest_played_song)
|
||||||
if !(Playlist.get_preloaded_songs() > 0):
|
if !(Playlist.get_preloaded_songs() > 0):
|
||||||
next_button.disabled = true
|
song_controls.set_next_enabled(false)
|
||||||
if !Playlist.is_song_downloading:
|
song_loader.fetch_song_if_idle()
|
||||||
fetch_song()
|
|
||||||
|
|
||||||
|
|
||||||
func _popups() -> Array[PopupWindow]:
|
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
|
# 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.
|
# avoids starting downloads while the user is still clicking the number up and down.
|
||||||
func _on_settings_window_visibility_changed() -> void:
|
func _on_settings_window_visibility_changed() -> void:
|
||||||
if !settings_window.visible && !Playlist.is_song_downloading && Playlist.should_preload_more_songs():
|
if !settings_window.visible:
|
||||||
fetch_song()
|
song_loader.fill_cache()
|
||||||
|
|
||||||
|
|
||||||
func fetch_song() -> void:
|
func _on_song_added() -> void:
|
||||||
print("fetch_song")
|
song_controls.set_next_enabled(true)
|
||||||
Playlist.is_song_downloading = true
|
if Settings.is_debug:
|
||||||
_download_random_song(SongObject.new())
|
update_song_list()
|
||||||
|
|
||||||
|
|
||||||
# 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 update_song_list() -> void:
|
func update_song_list() -> void:
|
||||||
print("update_song_list")
|
print("update_song_list")
|
||||||
if Playlist.currently_playing_song >= 0:
|
if Playlist.currently_playing_song >= 0:
|
||||||
soundtrack_label.text = Playlist.get_current_soundtrack_title()
|
now_playing.show_song(Playlist.get_current_soundtrack_title(),
|
||||||
song_label.text = Playlist.get_current_song_title()
|
Playlist.get_current_song_title())
|
||||||
music_list_panel.refresh()
|
music_list_panel.refresh()
|
||||||
|
|
||||||
|
|
||||||
@@ -304,7 +212,7 @@ func reset_playlist() -> void:
|
|||||||
print("reset_playlist")
|
print("reset_playlist")
|
||||||
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
|
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
|
||||||
Playlist.reset_playlist()
|
Playlist.reset_playlist()
|
||||||
fetch_song_list_at_start()
|
song_loader.load_song_list()
|
||||||
|
|
||||||
MusicServerClient.reset_playlist(playlist_reset_done)
|
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.
|
## Presses Next and waits until the first song is playing.
|
||||||
func _play_first_song() -> void:
|
func _play_first_song() -> void:
|
||||||
_press("NextButton")
|
_press("SongControls/NextButton")
|
||||||
await _runner.simulate_frames(2)
|
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.
|
## Nodes that moved from the main window into the Quiz scene, by their old name.
|
||||||
const QUIZ_NODES: Array[String] = [
|
const QUIZ_NODES: Array[String] = [
|
||||||
"Open", "FileDialog", "MusicListPanel", "VBoxContainer",
|
"Open", "FileDialog", "MusicListPanel", "DebugLabel", "SettingsWindow",
|
||||||
"MusicPlayer", "ResetPlaylistButton", "ResetPointsButton", "SettingsButton",
|
"NewCharacterSelect", "WinnerWindow", "Log",
|
||||||
"SoundTestButton", "ShowAnswerButton", "NextButton", "RepeatSongCheckButton",
|
|
||||||
"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 = {
|
const RENAMED_QUIZ_NODES: Dictionary = {
|
||||||
"Players": "PlayersPanel",
|
"Players": "PlayersPanel",
|
||||||
"ScrollContainer": "InspirationList",
|
"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.
|
## 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_int(_server.count("/music/all")).is_equal(1)
|
||||||
assert_array(_server.requested_paths).contains(["/music/rand", "/music/addQue", "/music/info"])
|
assert_array(_server.requested_paths).contains(["/music/rand", "/music/addQue", "/music/info"])
|
||||||
assert_int(Playlist.song_object_array.size()).is_equal(1)
|
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:
|
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(
|
_server.respond_bytes(
|
||||||
"/music/rand/low", FileAccess.get_file_as_bytes("res://tests/data/short.mp3"))
|
"/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)
|
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:
|
func test_next_plays_preloaded_song_and_fetches_another() -> void:
|
||||||
_next_song_is(SONG_INFO[1])
|
_next_song_is(SONG_INFO[1])
|
||||||
|
|
||||||
_press("NextButton")
|
_press("SongControls/NextButton")
|
||||||
await _runner.simulate_frames(2)
|
await _runner.simulate_frames(2)
|
||||||
|
|
||||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
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:
|
func test_title_is_hidden_until_answer_is_shown() -> void:
|
||||||
var soundtrack_label: Label = _quiz.get_node("VBoxContainer/SoundtrackLabel")
|
var soundtrack_label: Label = _quiz.get_node("NowPlaying/SoundtrackLabel")
|
||||||
_press("NextButton")
|
_press("SongControls/NextButton")
|
||||||
await _runner.simulate_frames(2)
|
await _runner.simulate_frames(2)
|
||||||
|
|
||||||
assert_str(soundtrack_label.text).is_equal("????????")
|
assert_str(soundtrack_label.text).is_equal("????????")
|
||||||
|
|
||||||
_press("ShowAnswerButton")
|
_press("SongControls/ShowAnswerButton")
|
||||||
|
|
||||||
assert_str(soundtrack_label.text).is_equal("Chrono Trigger")
|
assert_str(soundtrack_label.text).is_equal("Chrono Trigger")
|
||||||
assert_int(_server.count("/music/played?song=0")).is_equal(1)
|
assert_int(_server.count("/music/played?song=0")).is_equal(1)
|
||||||
|
|
||||||
|
|
||||||
func test_reset_playlist_clears_server_and_preloads_again() -> void:
|
func test_reset_playlist_clears_server_and_preloads_again() -> void:
|
||||||
_press("NextButton")
|
_press("SongControls/NextButton")
|
||||||
await _runner.simulate_frames(2)
|
await _runner.simulate_frames(2)
|
||||||
|
|
||||||
_press("ResetPlaylistButton")
|
_press("QuizToolbar/ResetPlaylistButton")
|
||||||
|
|
||||||
assert_int(_server.count("/music/reset")).is_equal(1)
|
assert_int(_server.count("/music/reset")).is_equal(1)
|
||||||
assert_int(Playlist.currently_playing_song).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("Crono").add_point()
|
||||||
_add_player("Marle").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[0].player_score).is_equal(0)
|
||||||
assert_int(Settings.player_array[1].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:
|
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 songs_before: int = Playlist.song_object_array.size()
|
||||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||||
_server.respond_bytes("/music/rand", PackedByteArray(), 503)
|
_server.respond_bytes("/music/rand", PackedByteArray(), 503)
|
||||||
var rand_requests_before: int = _server.count("/music/rand")
|
var rand_requests_before: int = _server.count("/music/rand")
|
||||||
|
|
||||||
_quiz.fetch_song()
|
_quiz.song_loader.fetch_song()
|
||||||
await await_millis(200)
|
await await_millis(200)
|
||||||
|
|
||||||
assert_int(_server.count("/music/rand") - rand_requests_before).is_greater(1)
|
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:
|
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()
|
var songs_before: int = Playlist.song_object_array.size()
|
||||||
_server.respond_bytes("/music/info", PackedByteArray(), 503)
|
_server.respond_bytes("/music/info", PackedByteArray(), 503)
|
||||||
var rand_before: int = _server.count("/music/rand")
|
var rand_before: int = _server.count("/music/rand")
|
||||||
var queue_before: int = _server.count("/music/addQue")
|
var queue_before: int = _server.count("/music/addQue")
|
||||||
|
|
||||||
_quiz.fetch_song()
|
_quiz.song_loader.fetch_song()
|
||||||
await await_millis(200)
|
await await_millis(200)
|
||||||
_next_song_is(SONG_INFO[1])
|
_next_song_is(SONG_INFO[1])
|
||||||
await await_millis(200)
|
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:
|
func test_preloads_as_many_songs_as_the_cache_setting() -> void:
|
||||||
Playlist.number_of_tracks_to_preload = 3
|
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_int(Playlist.get_preloaded_songs()).is_equal(3)
|
||||||
assert_bool(Playlist.is_song_downloading).is_false()
|
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:
|
func test_playing_a_song_tops_the_cache_up_again() -> void:
|
||||||
Playlist.number_of_tracks_to_preload = 3
|
Playlist.number_of_tracks_to_preload = 3
|
||||||
_quiz.fetch_song()
|
_quiz.song_loader.fetch_song()
|
||||||
|
|
||||||
await _play_first_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:
|
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
|
Playlist.number_of_tracks_to_preload = 3
|
||||||
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
var mp3: PackedByteArray = FileAccess.get_file_as_bytes("res://tests/data/short.mp3")
|
||||||
# One more download works, then the server stops answering
|
# One more download works, then the server stops answering
|
||||||
_server.fail_after("/music/rand", 1)
|
_server.fail_after("/music/rand", 1)
|
||||||
|
|
||||||
_quiz.fetch_song()
|
_quiz.song_loader.fetch_song()
|
||||||
await await_millis(150)
|
await await_millis(150)
|
||||||
|
|
||||||
assert_int(Playlist.get_preloaded_songs()).is_equal(2)
|
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:
|
func _open_settings() -> void:
|
||||||
_press("SettingsButton")
|
_press("QuizToolbar/SettingsButton")
|
||||||
|
|
||||||
|
|
||||||
func _close_settings() -> void:
|
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:
|
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_bool(Playlist.song_object_array[0].is_answered).is_false()
|
||||||
assert_int(_server.count("/music/played?song=-1")).is_equal(0)
|
assert_int(_server.count("/music/played?song=-1")).is_equal(0)
|
||||||
|
|
||||||
await _play_first_song()
|
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("????????")
|
.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:
|
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.respond_json("/music/list", [], 503)
|
||||||
_server.release("/music/list")
|
_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:
|
func test_closing_click_does_not_press_button_behind_popup() -> void:
|
||||||
var settings: PopupWindow = _popup("SettingsWindow")
|
var settings: PopupWindow = _popup("SettingsWindow")
|
||||||
var reset_button: Button = _quiz.get_node("ResetPlaylistButton")
|
var reset_button: Button = _quiz.get_node("QuizToolbar/ResetPlaylistButton")
|
||||||
settings.open()
|
settings.open()
|
||||||
await _runner.simulate_frames(1)
|
await _runner.simulate_frames(1)
|
||||||
assert_bool(settings.panel.get_global_rect().intersects(reset_button.get_global_rect())) \
|
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:
|
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())
|
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:
|
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) \
|
assert_str(_quiz.get_node(node_name).scene_file_path) \
|
||||||
.is_equal("res://%s.tscn" % node_name)
|
.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:
|
func test_top_bar_holds_only_title_and_buttons() -> void:
|
||||||
assert_array(_children(_window.get_node("TopBar"))) \
|
assert_array(_children(_window.get_node("TopBar"))) \
|
||||||
.contains_exactly_in_any_order(TOP_BAR_CHILDREN)
|
.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:
|
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)
|
await _runner.simulate_frames(2)
|
||||||
assert_int(Playlist.currently_playing_song).is_equal(0)
|
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")
|
.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")
|
.is_equal("Chrono Trigger")
|
||||||
|
|
||||||
|
|
||||||
func test_clicking_a_song_in_the_music_list_plays_it() -> void:
|
func test_clicking_a_song_in_the_music_list_plays_it() -> void:
|
||||||
_next_song_is(SONG_INFO[1])
|
_next_song_is(SONG_INFO[1])
|
||||||
await _play_first_song()
|
await _play_first_song()
|
||||||
_press("NextButton")
|
_press("SongControls/NextButton")
|
||||||
# Changing song waits a moment for the old one to stop
|
# Changing song waits a moment for the old one to stop
|
||||||
await get_tree().create_timer(0.7).timeout
|
await get_tree().create_timer(0.7).timeout
|
||||||
assert_int(Playlist.currently_playing_song).is_equal(1)
|
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)
|
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:
|
func test_quiz_popup_backdrop_covers_the_top_bar() -> void:
|
||||||
var settings: PopupWindow = _quiz.get_node("SettingsWindow")
|
var settings: PopupWindow = _quiz.get_node("SettingsWindow")
|
||||||
settings.open()
|
settings.open()
|
||||||
@@ -169,8 +203,8 @@ func test_sync_disables_quiz_buttons_until_finished() -> void:
|
|||||||
_top_bar_button("SyncButton").pressed.emit()
|
_top_bar_button("SyncButton").pressed.emit()
|
||||||
sync_window.sync_timer.stop()
|
sync_window.sync_timer.stop()
|
||||||
|
|
||||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||||
"NextButton"]:
|
"SongControls/NextButton"]:
|
||||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||||
.override_failure_message(button_name + " not disabled").is_true()
|
.override_failure_message(button_name + " not disabled").is_true()
|
||||||
assert_bool(_top_bar_button("SyncButton").disabled).is_false()
|
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()
|
sync_window._on_sync_timeout()
|
||||||
await _runner.simulate_frames(2)
|
await _runner.simulate_frames(2)
|
||||||
|
|
||||||
for button_name: String in ["SoundTestButton", "ResetPlaylistButton", "ShowAnswerButton",
|
for button_name: String in ["QuizToolbar/SoundTestButton", "QuizToolbar/ResetPlaylistButton", "SongControls/ShowAnswerButton",
|
||||||
"NextButton"]:
|
"SongControls/NextButton"]:
|
||||||
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
assert_bool((_quiz.get_node(button_name) as Button).disabled) \
|
||||||
.override_failure_message(button_name + " still disabled").is_false()
|
.override_failure_message(button_name + " still disabled").is_false()
|
||||||
# The search list in the main window and the quiz playlist are both reloaded
|
# 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:
|
func test_resetting_points_turns_statistics_back_on() -> void:
|
||||||
await _give_point_with_keybind(1)
|
await _give_point_with_keybind(1)
|
||||||
|
|
||||||
_press("ResetPointsButton")
|
_press("QuizToolbar/ResetPointsButton")
|
||||||
|
|
||||||
assert_bool(Settings.add_to_stats).is_true()
|
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
|
Settings.add_to_stats = false
|
||||||
await _give_point_with_keybind(1)
|
await _give_point_with_keybind(1)
|
||||||
|
|
||||||
_press("ResetPointsButton")
|
_press("QuizToolbar/ResetPointsButton")
|
||||||
|
|
||||||
assert_bool(Settings.add_to_stats).is_false()
|
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:
|
func test_settings_checkbox_shows_statistics_off_after_win() -> void:
|
||||||
await _give_point_with_keybind(1)
|
await _give_point_with_keybind(1)
|
||||||
|
|
||||||
_press("SettingsButton")
|
_press("QuizToolbar/SettingsButton")
|
||||||
|
|
||||||
assert_bool(_stats_checkbox().button_pressed).is_false()
|
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)
|
await _give_point_with_keybind(1)
|
||||||
var played_before: int = _server.count("/music/played?song=0")
|
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)
|
assert_int(_server.count("/music/played?song=0")).is_equal(played_before)
|
||||||
|
|
||||||
|
|
||||||
func test_winning_score_cannot_go_below_one() -> void:
|
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")
|
var lower_button: Button = _quiz.get_node("SettingsWindow").get_node("%LowerButton")
|
||||||
|
|
||||||
for i: int in 3:
|
for i: int in 3:
|
||||||
|
|||||||
Reference in new issue
Block a user