Skip to content

Commit

Permalink
fix(boxart): Run fetching of boxart in its own io thread and implemen…
Browse files Browse the repository at this point in the history
…t transitions in visibility manager
  • Loading branch information
ShadowApex committed Mar 31, 2023
1 parent 822d3cc commit 881a083
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 22 deletions.
9 changes: 9 additions & 0 deletions core/global/boxart_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class_name BoxArtManager
## [/codeblock]

const SettingsManager := preload("res://core/global/settings_manager.tres")
const io_thread = preload("res://core/systems/threading/io_thread.tres")

## Fields required to be set by [BoxArtProvider] implementations
const REQUIRED_FIELDS: Array = ["provider_id"]
Expand All @@ -44,8 +45,16 @@ var _providers: Dictionary = {}
var _providers_by_priority: Array = []


func _init() -> void:
io_thread.start()


## Returns the boxart of the given kind for the given library item.
func get_boxart(item: LibraryItem, kind: BoxArtProvider.LAYOUT) -> Texture2D:
return await io_thread.exec(_get_boxart_sync.bind(item, kind))


func _get_boxart_sync(item: LibraryItem, kind: BoxArtProvider.LAYOUT) -> Texture2D:
if _providers.is_empty():
logger.error("No box art providers were found!")
return null
Expand Down
67 changes: 64 additions & 3 deletions core/systems/state/visibility_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,44 @@
extends Node
class_name VisibilityManager

signal transition_started
signal transition_finished
signal entered
signal exited

# State machine to use
@export var state_machine: StateMachine = preload(
"res://assets/state/state_machines/global_state_machine.tres"
)
@export var state: State
@export var visible_during: Array[Resource] = []

var logger := Log.get_logger("VisibilityManager")
var _transitions: Array[Transition] = []
var logger := Log.get_logger("VisibilityManager", Log.LEVEL.INFO)
@onready var _parent := get_parent() as CanvasItem


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
state_machine.state_changed.connect(_on_state_changed)
visible_during.push_front(state)

# Handle visibility transitions
var children := get_children()
for child in children:
if not child is Transition:
continue

var transition := child as Transition
if not transition.has_animation(transition.enter_animation):
logger.warn("Transition {0} doesn't have enter animation {1}".format([transition.name, transition.enter_animation]))
continue
if not transition.has_animation(transition.exit_animation):
logger.warn("Transition {0} doesn't have exit animation {1}".format([transition.name, transition.exit_animation]))
continue

_transitions.append(transition)
transition.root_node = "../.."


func _on_state_changed(_from: State, to: State) -> void:
Expand All @@ -31,13 +54,51 @@ func _transition(visibility: bool) -> void:
_parent.z_index = state_machine.stack().find(state)

# If the parent doesn't have any transitions, flip visibility
if not _parent.has_node("TransitionContainer"):
if not has_transitions():
_parent.visible = visibility
return

# Use transitions if they exist
# Prefer transitions that are children of visibilitymanager
if _transitions.size() > 0:
if visibility:
enter()
return
exit()
return

# Use transition containers if they exist
var transition := _parent.get_node("TransitionContainer") as TransitionContainer
if visibility:
transition.enter()
return
transition.exit()


func has_transitions() -> bool:
if _transitions.size() > 0 or _parent.has_node("TransitionContainer"):
return true
return false


func enter() -> void:
for transition in _transitions:
transition.play(transition.enter_animation)
transition_started.emit()

for transition in _transitions:
var anim = await transition.animation_finished
logger.debug("Finished playing: " + anim)
transition_finished.emit()
entered.emit()


func exit() -> void:
for transition in _transitions:
transition.play(transition.exit_animation)
transition_started.emit()

for transition in _transitions:
var anim = await transition.animation_finished
logger.debug("Finished playing: " + anim)
transition_finished.emit()
exited.emit()
8 changes: 8 additions & 0 deletions core/systems/threading/io_thread.tres
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="SharedThread" load_steps=2 format=3 uid="uid://ka4mdlcnbil3"]

[ext_resource type="Script" path="res://core/systems/threading/shared_thread.gd" id="1_qvlys"]

[resource]
script = ExtResource("1_qvlys")
name = "IOThread"
target_tick_rate = 30
2 changes: 2 additions & 0 deletions core/ui/components/transition_container.gd
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
extends Node
class_name TransitionContainer

## DEPRECATED - Add transitions to VisibilityManager instead

signal transition_started
signal transition_finished
signal entered
Expand Down
112 changes: 112 additions & 0 deletions core/ui/components/transition_slide_down.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[gd_scene load_steps=6 format=3 uid="uid://61bw8lmqymry"]

[ext_resource type="Script" path="res://core/ui/components/transition.gd" id="1_86nlo"]

[sub_resource type="Animation" id="Animation_d13hk"]
resource_name = "enter"
length = 0.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0.1, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector2(0, -500), Vector2(0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.1, 0.5),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.1),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}

[sub_resource type="Animation" id="Animation_qrxbs"]
resource_name = "exit"
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:visible")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}

[sub_resource type="Animation" id="Animation_5ykde"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 1)]
}

[sub_resource type="AnimationLibrary" id="AnimationLibrary_igt3d"]
_data = {
"RESET": SubResource("Animation_5ykde"),
"enter": SubResource("Animation_d13hk"),
"exit": SubResource("Animation_qrxbs")
}

[node name="SlideTransition" type="AnimationPlayer"]
root_node = NodePath("../..")
libraries = {
"": SubResource("AnimationLibrary_igt3d")
}
script = ExtResource("1_86nlo")
8 changes: 4 additions & 4 deletions core/ui/menu/home/home_menu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ var main_menu_state := preload("res://assets/state/states/main_menu.tres") as St
var launcher_state := preload("res://assets/state/states/game_launcher.tres") as State
var poster_scene := preload("res://core/ui/components/poster.tscn") as PackedScene
var _initialized := false
var recent_apps: Array

@onready var container: HBoxContainer = $MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/HBoxContainer
@onready var container: HBoxContainer = $%PostersContainer
@onready var banner: TextureRect = $SelectedBanner
@onready var player: AnimationPlayer = $AnimationPlayer
var recent_apps: Array


# Called when the node enters the scene tree for the first time.
Expand All @@ -22,7 +22,6 @@ func _ready() -> void:
for child in container.get_children():
if child.name == "LibraryPoster":
continue
container.remove_child(child)
child.queue_free()

LibraryManager.library_reloaded.connect(_on_library_reloaded)
Expand Down Expand Up @@ -98,7 +97,7 @@ func _on_recent_apps_updated() -> void:
items[name] = library_item

# Populate our grid with items
_repopulate_grid(container, items.values())
await _repopulate_grid(container, items.values())
_grab_focus()


Expand Down Expand Up @@ -128,6 +127,7 @@ func _build_poster(item: LibraryItem, portrait: bool) -> TextureButton:
poster.layout = poster.LAYOUT_MODE.PORTRAIT
else:
poster.layout = poster.LAYOUT_MODE.LANDSCAPE
poster.name = item.name
poster.text = item.name
poster.layout_scale = 1.4

Expand Down
19 changes: 10 additions & 9 deletions core/ui/menu/home/home_menu.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
[ext_resource type="Shader" path="res://assets/shaders/outline.gdshader" id="12_fa67h"]
[ext_resource type="Texture2D" uid="uid://dkdoyup6wajvq" path="res://assets/images/library-grid-portrait.png" id="17_7n7ug"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_grjtv"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_31pe1"]
resource_local_to_scene = true
shader = ExtResource("12_fa67h")
shader_parameter/on = false
Expand Down Expand Up @@ -57,7 +57,7 @@ launch_items = [SubResource("Resource_gsruu")]
tags = null
categories = null

[sub_resource type="ShaderMaterial" id="ShaderMaterial_5tph2"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_meu0h"]
resource_local_to_scene = true
shader = ExtResource("12_fa67h")
shader_parameter/on = false
Expand Down Expand Up @@ -170,23 +170,24 @@ theme_override_constants/margin_top = 50
theme_override_constants/margin_right = 50
theme_override_constants/margin_bottom = 50

[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer"]
[node name="PostersContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
theme_override_constants/separation = 16

[node name="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/HBoxContainer" instance=ExtResource("4_k6kif")]
material = SubResource("ShaderMaterial_grjtv")
[node name="Button" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/PostersContainer" instance=ExtResource("4_k6kif")]
material = SubResource("ShaderMaterial_31pe1")
custom_minimum_size = Vector2(200.2, 301)
layout_mode = 2
text = "vkCube"
layout = 1
layout_scale = 1.4

[node name="Launcher" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/HBoxContainer/Button" instance=ExtResource("5_0bpdu")]
[node name="Launcher" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/PostersContainer/Button" instance=ExtResource("5_0bpdu")]
library_item = SubResource("Resource_icex7")

[node name="LibraryPoster" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/HBoxContainer" instance=ExtResource("4_k6kif")]
material = SubResource("ShaderMaterial_5tph2")
[node name="LibraryPoster" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/PostersContainer" instance=ExtResource("4_k6kif")]
material = SubResource("ShaderMaterial_meu0h")
custom_minimum_size = Vector2(200.2, 301)
layout_mode = 2
texture_normal = ExtResource("17_7n7ug")
Expand All @@ -195,7 +196,7 @@ text = "Library"
layout = 1
layout_scale = 1.4

[node name="StateUpdater" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/HBoxContainer/LibraryPoster" instance=ExtResource("9_8yw4g")]
[node name="StateUpdater" parent="MarginContainer/VBoxContainer/ScrollContainer/MarginContainer/PostersContainer/LibraryPoster" instance=ExtResource("9_8yw4g")]
state_machine = ExtResource("10_tl8ss")
state = ExtResource("11_lws2k")
on_signal = "button_up"
Expand Down
10 changes: 5 additions & 5 deletions core/ui/menu/launch/game_launch_menu.gd
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
extends Control

const SettingsManager := preload("res://core/global/settings_manager.tres")
const LaunchManager := preload("res://core/global/launch_manager.tres")
const LibraryManager := preload("res://core/global/library_manager.tres")
const NotificationManager := preload("res://core/global/notification_manager.tres")
const BoxArtManager := preload("res://core/global/boxart_manager.tres")
var SettingsManager := preload("res://core/global/settings_manager.tres")
var LaunchManager := preload("res://core/global/launch_manager.tres")
var NotificationManager := preload("res://core/global/notification_manager.tres")
var BoxArtManager := preload("res://core/global/boxart_manager.tres")
var LibraryManager := preload("res://core/global/library_manager.tres")

var state_machine := (
preload("res://assets/state/state_machines/global_state_machine.tres") as StateMachine
Expand Down
9 changes: 8 additions & 1 deletion core/ui/menu/launch/game_launch_menu.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://bwl2icwgry4l"]
[gd_scene load_steps=22 format=3 uid="uid://bwl2icwgry4l"]

[ext_resource type="Script" path="res://core/ui/menu/launch/game_launch_menu.gd" id="1_uhkt4"]
[ext_resource type="Theme" uid="uid://bko0q7gp1hwjp" path="res://assets/themes/dracula.tres" id="2_q87np"]
Expand All @@ -15,6 +15,7 @@
[ext_resource type="PackedScene" uid="uid://ccd4sw84h1qbc" path="res://core/systems/input/back_input_handler.tscn" id="8_hg7ac"]
[ext_resource type="Resource" uid="uid://bw0mtk7sso8m2" path="res://assets/state/states/power_menu.tres" id="8_jwh6r"]
[ext_resource type="PackedScene" uid="uid://2tdbi1v6qb6h" path="res://core/ui/components/loading02.tscn" id="11_8fkuv"]
[ext_resource type="PackedScene" uid="uid://61bw8lmqymry" path="res://core/ui/components/transition_slide_down.tscn" id="11_ei0vn"]
[ext_resource type="Resource" uid="uid://cx8u1y5j7vyss" path="res://assets/state/states/gamepad_settings.tres" id="16_0i4he"]
[ext_resource type="PackedScene" uid="uid://b76dvfuouhlwd" path="res://core/systems/state/state_updater.tscn" id="16_d1x8e"]
[ext_resource type="Resource" uid="uid://cr544el0cqjlm" path="res://assets/state/state_machines/global_state_machine.tres" id="17_yolrd"]
Expand Down Expand Up @@ -61,6 +62,12 @@ layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 20

[node name="VisibilityManager" parent="ScrollContainer/VBoxContainer" instance=ExtResource("2_sp632")]
state = ExtResource("3_68ilj")
visible_during = Array[Resource]([ExtResource("4_mab76"), ExtResource("5_ejgx3"), ExtResource("6_t3rni"), ExtResource("7_2y6wm"), ExtResource("8_jwh6r")])

[node name="SlideTransition" parent="ScrollContainer/VBoxContainer/VisibilityManager" instance=ExtResource("11_ei0vn")]

[node name="GameBanner" type="TextureRect" parent="ScrollContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 440)
layout_mode = 2
Expand Down

0 comments on commit 881a083

Please sign in to comment.