mirror of
https://github.com/thegatesbrowser/thegates.git
synced 2025-08-24 11:17:26 -04:00
162 lines
4.3 KiB
GDScript
162 lines
4.3 KiB
GDScript
extends Control
|
|
|
|
enum ProgressStatus {
|
|
CONNECTING,
|
|
DOWNLOADING,
|
|
STARTING,
|
|
ERROR
|
|
}
|
|
|
|
class DownloadItem:
|
|
var body_size: int
|
|
var downloaded_bytes: int
|
|
|
|
@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 = 300
|
|
const ZERO_SPEED_DELAY_MS = 2000
|
|
|
|
var download_items: Dictionary
|
|
|
|
# For calculating speed
|
|
var last_bytes: int
|
|
var last_ticks: int
|
|
var last_speed: String
|
|
var last_is_zero: bool
|
|
var first_zero_ticks: int
|
|
|
|
|
|
func _ready() -> void:
|
|
gate_events.gate_info_loaded.connect(on_gate_info_loaded)
|
|
gate_events.gate_entered.connect(on_gate_entered)
|
|
gate_events.gate_error.connect(on_gate_error)
|
|
set_progress("Connecting...", ProgressStatus.CONNECTING)
|
|
|
|
|
|
func on_gate_info_loaded(_gate: Gate) -> void:
|
|
gate_events.download_progress.connect(show_progress)
|
|
last_ticks = Time.get_ticks_msec()
|
|
|
|
|
|
func show_progress(url: String, body_size: int, downloaded_bytes: int) -> void:
|
|
if body_size < 0: return
|
|
|
|
var item = download_items.get_or_add(url, DownloadItem.new()) as DownloadItem
|
|
item.body_size = body_size
|
|
item.downloaded_bytes = downloaded_bytes
|
|
|
|
var sum_downloaded_bytes = get_sum(&"downloaded_bytes")
|
|
var sum_body_size = get_sum(&"body_size")
|
|
|
|
var downloaded = StringTools.bytes_to_string(sum_downloaded_bytes)
|
|
var body = StringTools.bytes_to_string(sum_body_size)
|
|
var speed = get_speed(sum_downloaded_bytes)
|
|
|
|
var text = "Downloading resources — %s of %s (%s/sec)" % [downloaded, body, speed]
|
|
var progress = float(sum_downloaded_bytes) / sum_body_size
|
|
set_progress(text, ProgressStatus.DOWNLOADING, progress)
|
|
|
|
|
|
func get_sum(property: StringName) -> int:
|
|
var result: int = 0
|
|
for item in download_items.values():
|
|
result += item.get(property)
|
|
return result
|
|
|
|
|
|
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() and not last_is_zero:
|
|
return last_speed
|
|
|
|
var bytes_sec = 0
|
|
if delta_bytes != 0 and delta_ticks != 0:
|
|
bytes_sec = int(delta_bytes / (delta_ticks / 1000.0))
|
|
|
|
if should_write_current_speed(bytes_sec):
|
|
last_bytes = bytes
|
|
last_ticks = Time.get_ticks_msec()
|
|
last_speed = StringTools.bytes_to_string(bytes_sec)
|
|
|
|
return last_speed
|
|
|
|
|
|
func should_write_current_speed(bytes_sec: int) -> bool:
|
|
if last_speed.is_empty():
|
|
last_is_zero = bytes_sec == 0
|
|
return true
|
|
|
|
if bytes_sec != 0:
|
|
last_is_zero = false
|
|
return true
|
|
|
|
if not last_is_zero:
|
|
first_zero_ticks = Time.get_ticks_msec()
|
|
last_is_zero = true
|
|
return false
|
|
|
|
var delta_zero_tiks = Time.get_ticks_msec() - first_zero_ticks
|
|
if delta_zero_tiks < ZERO_SPEED_DELAY_MS:
|
|
return false
|
|
|
|
return true
|
|
|
|
|
|
func on_gate_entered() -> void:
|
|
gate_events.download_progress.disconnect(show_progress)
|
|
set_progress("Starting the gate...", ProgressStatus.STARTING)
|
|
|
|
|
|
func on_gate_error(code: GateEvents.GateError) -> void:
|
|
match code:
|
|
GateEvents.GateError.NOT_FOUND:
|
|
set_progress("Gate not found", ProgressStatus.ERROR)
|
|
GateEvents.GateError.INVALID_CONFIG:
|
|
set_progress("Gate not found", ProgressStatus.ERROR)
|
|
GateEvents.GateError.MISSING_PACK, GateEvents.GateError.MISSING_LIBS:
|
|
set_progress("Cannot load gate resources", ProgressStatus.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, 0.0)
|
|
|
|
ProgressStatus.DOWNLOADING:
|
|
progress_bar.show()
|
|
progress_bar_error.hide()
|
|
move_progress_bar(progress, FileDownloader.PROGRESS_DELAY)
|
|
|
|
ProgressStatus.STARTING:
|
|
progress_bar.show()
|
|
progress_bar_error.hide()
|
|
move_progress_bar(1.0, TWEEN_DURATION_S)
|
|
|
|
ProgressStatus.ERROR:
|
|
progress_bar.hide()
|
|
progress_bar_error.show()
|
|
|
|
_:
|
|
progress_bar.hide()
|
|
progress_bar_error.hide()
|
|
|
|
|
|
func move_progress_bar(progress: float, tween_duration: float) -> void:
|
|
var full_size = progress_bar_background.size
|
|
var current_size = Vector2(lerp(0.0, full_size.x, progress), full_size.y)
|
|
|
|
var tween = get_tree().create_tween()
|
|
tween.tween_property(progress_bar, "size", current_size, tween_duration)
|