From ebd3b049e0ad3a2f84557a715c870df664f139b7 Mon Sep 17 00:00:00 2001 From: Nordup Date: Thu, 5 Dec 2024 11:15:43 +0400 Subject: [PATCH] loading status --- .../{gate_status.tscn => loading_tatus.tscn} | 29 ++++- app/scenes/menu.tscn | 2 - app/scenes/menu_body/world.tscn | 6 +- app/scripts/loading/config_gate.gd | 13 +-- app/scripts/loading/file_downloader.gd | 7 +- app/scripts/ui/menu/window_buttons.gd | 6 +- app/scripts/ui/world/loading_status.gd | 109 ++++++++++++++++-- app/scripts/ui/world/loading_ui.gd | 12 -- app/scripts/ui/world/not_responding.gd | 6 +- app/shaders/vignette_blur.tres | 1 - 10 files changed, 146 insertions(+), 45 deletions(-) rename app/scenes/components/{gate_status.tscn => loading_tatus.tscn} (56%) delete mode 100644 app/scripts/ui/world/loading_ui.gd diff --git a/app/scenes/components/gate_status.tscn b/app/scenes/components/loading_tatus.tscn similarity index 56% rename from app/scenes/components/gate_status.tscn rename to app/scenes/components/loading_tatus.tscn index 5213284..f4eabf7 100644 --- a/app/scenes/components/gate_status.tscn +++ b/app/scenes/components/loading_tatus.tscn @@ -1,6 +1,8 @@ -[gd_scene load_steps=4 format=3 uid="uid://dr1hykfog1h85"] +[gd_scene load_steps=7 format=3 uid="uid://dr1hykfog1h85"] [ext_resource type="LabelSettings" uid="uid://bo2334w4lf3ug" path="res://assets/styles/text.tres" id="1_gjtj0"] +[ext_resource type="Script" path="res://scripts/ui/world/loading_status.gd" id="1_m3y11"] +[ext_resource type="Resource" uid="uid://b1xvdym0qh6td" path="res://resources/gate_events.res" id="2_0ylq1"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ydgjs"] bg_color = Color(0.431373, 0.435294, 0.494118, 1) @@ -9,6 +11,13 @@ corner_radius_top_right = 3 corner_radius_bottom_right = 3 corner_radius_bottom_left = 3 +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fgqyr"] +bg_color = Color(0.933333, 0.235294, 0.243137, 1) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_t3wmh"] bg_color = Color(0.32549, 0.14902, 0.8, 1) corner_radius_top_left = 3 @@ -16,22 +25,36 @@ corner_radius_top_right = 3 corner_radius_bottom_right = 3 corner_radius_bottom_left = 3 -[node name="GateStatus" type="Control"] +[node name="LoadingStatus" type="Control" node_paths=PackedStringArray("progress_bar_background", "progress_bar_error", "progress_bar", "label")] custom_minimum_size = Vector2(0, 35) layout_mode = 3 anchors_preset = 0 offset_right = 512.0 offset_bottom = 35.0 +script = ExtResource("1_m3y11") +gate_events = ExtResource("2_0ylq1") +progress_bar_background = NodePath("ProgressBarBackground") +progress_bar_error = NodePath("ProgressBarError") +progress_bar = NodePath("ProgressBar") +label = NodePath("Label") [node name="ProgressBarBackground" type="Panel" parent="."] custom_minimum_size = Vector2(0, 6) layout_mode = 1 anchors_preset = 10 anchor_right = 1.0 -offset_bottom = 6.0 grow_horizontal = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_ydgjs") +[node name="ProgressBarError" type="Panel" parent="."] +visible = false +custom_minimum_size = Vector2(0, 6) +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_fgqyr") + [node name="ProgressBar" type="Panel" parent="."] custom_minimum_size = Vector2(0, 6) layout_mode = 1 diff --git a/app/scenes/menu.tscn b/app/scenes/menu.tscn index f24f8af..601bb01 100644 --- a/app/scenes/menu.tscn +++ b/app/scenes/menu.tscn @@ -121,12 +121,10 @@ exit = NodePath("Close") [node name="Minimize" parent="VBoxContainer/Top/VBoxContainer/Tabs/WindowButtons" instance=ExtResource("6_gxcmo")] layout_mode = 2 -disabled = true icon = ExtResource("7_ab04l") [node name="Maximize" parent="VBoxContainer/Top/VBoxContainer/Tabs/WindowButtons" instance=ExtResource("6_gxcmo")] layout_mode = 2 -disabled = true icon = ExtResource("8_yoyw7") [node name="Close" parent="VBoxContainer/Top/VBoxContainer/Tabs/WindowButtons" instance=ExtResource("6_gxcmo")] diff --git a/app/scenes/menu_body/world.tscn b/app/scenes/menu_body/world.tscn index d563b56..bc533e7 100644 --- a/app/scenes/menu_body/world.tscn +++ b/app/scenes/menu_body/world.tscn @@ -27,7 +27,7 @@ [ext_resource type="FontFile" uid="uid://b3xb1fpllhnf4" path="res://assets/fonts/Inter-Italic.otf" id="21_lpegk"] [ext_resource type="FontFile" uid="uid://tfj3o1e1wytn" path="res://assets/fonts/Inter-BoldItalic.otf" id="22_i5khx"] [ext_resource type="FontFile" uid="uid://c14w1y1r54wgi" path="res://assets/fonts/Inter-Bold.otf" id="23_t1gqo"] -[ext_resource type="PackedScene" uid="uid://dr1hykfog1h85" path="res://scenes/components/gate_status.tscn" id="25_3436m"] +[ext_resource type="PackedScene" uid="uid://dr1hykfog1h85" path="res://scenes/components/loading_tatus.tscn" id="25_3436m"] [ext_resource type="Script" path="res://scripts/ui/world/release_focus.gd" id="26_u6afs"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_be6ex"] @@ -278,7 +278,7 @@ image = NodePath("Image/TextureRect") image_darken = NodePath("Image/Panel") title = NodePath("Title") description = NodePath("RichTextLabel") -gate_status = [NodePath("Space2"), NodePath("GateStatus")] +gate_status = [NodePath("Space2"), NodePath("LoadingStatus")] [node name="Image" type="Panel" parent="Foreground/GateInfo"] clip_children = 1 @@ -360,7 +360,7 @@ script = ExtResource("26_u6afs") custom_minimum_size = Vector2(0, 16) layout_mode = 2 -[node name="GateStatus" parent="Foreground/GateInfo" instance=ExtResource("25_3436m")] +[node name="LoadingStatus" parent="Foreground/GateInfo" instance=ExtResource("25_3436m")] layout_mode = 2 [node name="AnimationPlayer" type="AnimationPlayer" parent="."] diff --git a/app/scripts/loading/config_gate.gd b/app/scripts/loading/config_gate.gd index 1c2ad53..08ad854 100644 --- a/app/scripts/loading/config_gate.gd +++ b/app/scripts/loading/config_gate.gd @@ -1,22 +1,21 @@ extends ConfigBase class_name ConfigGate +const SECTION = "gate" + var title: String var description: String var image_url: String var resource_pack_url: String var libraries: PackedStringArray -const section = "gate" -const libs_section = "libraries" - func _init(path: String, base_url: String) -> void: super._init(path) - title = get_string(section, "title") - description = get_string(section, "description") - image_url = Url.join(base_url, get_string(section, "image")) - resource_pack_url = Url.join(base_url, get_string(section, "resource_pack")) + title = get_string(SECTION, "title") + description = get_string(SECTION, "description") + image_url = Url.join(base_url, get_string(SECTION, "image")) + resource_pack_url = Url.join(base_url, get_string(SECTION, "resource_pack")) libraries = get_libraries(base_url) diff --git a/app/scripts/loading/file_downloader.gd b/app/scripts/loading/file_downloader.gd index 48c0957..733091a 100644 --- a/app/scripts/loading/file_downloader.gd +++ b/app/scripts/loading/file_downloader.gd @@ -1,5 +1,7 @@ extends Node +signal progress(url: String, body_size: int, downloaded_bytes: int) + class DownloadRequest: var save_path: String var http: HTTPRequest @@ -11,9 +13,7 @@ class DownloadRequest: timer = _timer const DOWNLOAD_FOLDER := "user://gates_data" -const PROGRESS_DELAY := 0.3 - -signal progress(url: String, body_size: int, downloaded_bytes: int) +const PROGRESS_DELAY := 0.1 var download_requests: Array[DownloadRequest] @@ -97,7 +97,6 @@ func create_request(url: String, save_path: String, timeout: float = 0) -> int: if err != OK: return err var code = (await http.request_completed)[1] - progress.emit(url, http.get_body_size(), http.get_downloaded_bytes()) timer.stop() remove_child(timer) remove_child(http) diff --git a/app/scripts/ui/menu/window_buttons.gd b/app/scripts/ui/menu/window_buttons.gd index 347a943..cd7ffcf 100644 --- a/app/scripts/ui/menu/window_buttons.gd +++ b/app/scripts/ui/menu/window_buttons.gd @@ -16,7 +16,11 @@ func on_minimize() -> void: func on_maximize() -> void: - DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED) + var mode = DisplayServer.window_get_mode() + if mode == DisplayServer.WINDOW_MODE_WINDOWED: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED) + else: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) func on_exit() -> void: diff --git a/app/scripts/ui/world/loading_status.gd b/app/scripts/ui/world/loading_status.gd index 2ec0a80..1b318d8 100644 --- a/app/scripts/ui/world/loading_status.gd +++ b/app/scripts/ui/world/loading_status.gd @@ -1,13 +1,32 @@ -extends Label +extends Control + +enum ProgressStatus { + CONNECTING, + DOWNLOADING, + STARTING, + ERROR +} @export var gate_events: GateEvents +@export var progress_bar_background: Control +@export var progress_bar_error: Control +@export var progress_bar: Control +@export var label: Label + +const TWEEN_DURATION_S = 0.2 +const SPEED_DELAY_MS = 400 + +var last_bytes: int +var last_ticks: int +var last_speed: String +var accum_bytes: int func _ready() -> void: gate_events.gate_info_loaded.connect(func(_gate, _is_cached): on_gate_info_loaded()) gate_events.gate_entered.connect(on_gate_entered) gate_events.gate_error.connect(on_gate_error) - set_text("Connecting...") + set_progress("Connecting...", ProgressStatus.CONNECTING) func on_gate_info_loaded() -> void: @@ -15,22 +34,94 @@ func on_gate_info_loaded() -> void: func show_progress(_url: String, body_size: int, downloaded_bytes: int) -> void: - var percent = int(downloaded_bytes * 100 / body_size) - set_text("Downloading: %d%s" % [percent, "%"]) + if body_size < 0: return + + var downloaded = bytes_to_string(downloaded_bytes) + var body = bytes_to_string(body_size) + var speed = get_speed(downloaded_bytes) + + var text = "Downloading resources — %s of %s (%s/sec)" % [downloaded, body, speed] + var progress = float(downloaded_bytes) / body_size + set_progress(text, ProgressStatus.DOWNLOADING, progress) + + +func get_speed(bytes: int) -> String: + var delta_bytes = bytes - last_bytes + var delta_ticks = Time.get_ticks_msec() - last_ticks + + if delta_ticks < SPEED_DELAY_MS and not last_speed.is_empty(): return last_speed + + last_bytes = bytes + last_ticks = Time.get_ticks_msec() + + if delta_bytes == 0 or delta_ticks == 0: + return bytes_to_string(0) + + var speed = int(delta_bytes / (delta_ticks / 1000.0)) + last_speed = bytes_to_string(speed) + return last_speed + + +func bytes_to_string(bytes: int) -> String: + if bytes < 1024: return str(bytes) + "B" + + var kb = bytes / 1024 + if kb < 1024: return str(kb) + "KB" + + var mb = kb / 1024.0 + var text = "%.1fMB" if mb < 10.0 else "%.0fMB" + return text % [mb] func on_gate_entered() -> void: gate_events.download_progress.disconnect(show_progress) - set_text("") + set_progress("Starting the gate...", ProgressStatus.STARTING) func on_gate_error(code: GateEvents.GateError) -> void: match code: GateEvents.GateError.NOT_FOUND: - set_text("Gate not found") + set_progress("Gate not found", ProgressStatus.ERROR) GateEvents.GateError.INVALID_CONFIG: - set_text("Invalid gate config") + set_progress("Invalid gate config", ProgressStatus.ERROR) GateEvents.GateError.MISSING_PACK, GateEvents.GateError.MISSING_LIBS: - set_text("Cannot load gate resources") + set_progress("Cannot load gate resources", ProgressStatus.ERROR) _: - set_text("Error") + set_progress("Unknown error", ProgressStatus.ERROR) + + +func set_progress(text: String, status: ProgressStatus, progress: float = 0.0) -> void: + label.text = text + + match status: + ProgressStatus.CONNECTING: + progress_bar.show() + progress_bar_error.hide() + move_progress_bar(0.0) + + ProgressStatus.DOWNLOADING: + progress_bar.show() + progress_bar_error.hide() + move_progress_bar(progress) + + ProgressStatus.STARTING: + progress_bar.show() + progress_bar_error.hide() + move_progress_bar(1.0, true) + + ProgressStatus.ERROR: + progress_bar.hide() + progress_bar_error.show() + + _: + progress_bar.hide() + progress_bar_error.hide() + + +func move_progress_bar(progress: float, custom_delay: bool = false) -> void: + var full_size = progress_bar_background.size + var current_size = Vector2(lerp(0.0, full_size.x, progress), full_size.y) + var tween_duration = TWEEN_DURATION_S if custom_delay else FileDownloader.PROGRESS_DELAY + + var tween = get_tree().create_tween() + tween.tween_property(progress_bar, "size", current_size, tween_duration) diff --git a/app/scripts/ui/world/loading_ui.gd b/app/scripts/ui/world/loading_ui.gd deleted file mode 100644 index 5683b55..0000000 --- a/app/scripts/ui/world/loading_ui.gd +++ /dev/null @@ -1,12 +0,0 @@ -extends Control - -@export var gate_events: GateEvents - - -func _ready() -> void: - gate_events.gate_entered.connect(hide_ui) - visible = true - - -func hide_ui() -> void: - visible = false diff --git a/app/scripts/ui/world/not_responding.gd b/app/scripts/ui/world/not_responding.gd index 792706c..985ff96 100644 --- a/app/scripts/ui/world/not_responding.gd +++ b/app/scripts/ui/world/not_responding.gd @@ -1,8 +1,5 @@ extends Control -const SHOWN = Color(1, 1, 1, 1) -const HIDDEN = Color(1, 1, 1, 0) - @export var gate_events: GateEvents @export var history: History @export var root: TextureButton @@ -11,6 +8,9 @@ const HIDDEN = Color(1, 1, 1, 0) @export var fade_in: float = 1.0 @export var fade_out: float = 0.2 +const SHOWN = Color(1, 1, 1, 1) +const HIDDEN = Color(1, 1, 1, 0) + var tween: Tween diff --git a/app/shaders/vignette_blur.tres b/app/shaders/vignette_blur.tres index bbedc18..64610ab 100644 --- a/app/shaders/vignette_blur.tres +++ b/app/shaders/vignette_blur.tres @@ -143,7 +143,6 @@ void fragment() { } " -graph_offset = Vector2(-708.833, 8.55267) mode = 1 modes/blend = 5 flags/light_only = false