gd: added input addon

This commit is contained in:
2025-05-27 19:20:46 +02:00
parent d8a1604af9
commit c8d8c7ec25
683 changed files with 21608 additions and 2 deletions

View File

@ -0,0 +1,103 @@
@tool
extends Node
const CACHE_DIR:String = "user://_guide_cache"
@onready var _sub_viewport:SubViewport = %SubViewport
@onready var _root:Node2D = %Root
@onready var _scene_holder = %SceneHolder
var _pending_requests:Array[Job] = []
var _current_request:Job = null
var _fetch_image:bool = false
func _ready():
# keep working when game is paused
process_mode = Node.PROCESS_MODE_ALWAYS
# don't needlessly eat performance
if _pending_requests.is_empty():
set_process(false)
func clear_cache():
var files = DirAccess.get_files_at(CACHE_DIR)
for file in files:
DirAccess.remove_absolute(CACHE_DIR + "/" + file)
## Makes an icon for the given input and returns a Texture2D with the icon. Icons
## are cached on disk so subsequent calls for the same input will be faster.
func make_icon(input:GUIDEInput, renderer:GUIDEIconRenderer, height_px:int) -> Texture2D:
DirAccess.make_dir_recursive_absolute(CACHE_DIR)
var cache_key = (str(height_px) + renderer.cache_key(input)).sha256_text()
var cache_path = "user://_guide_cache/" + cache_key + ".res"
if ResourceLoader.exists(cache_path):
return ResourceLoader.load(cache_path, "Texture2D")
var job = Job.new()
job.height = height_px
job.input = input
job.renderer = renderer
_pending_requests.append(job)
set_process(true)
await job.done
var image_texture = ImageTexture.create_from_image(job.result)
ResourceSaver.save(image_texture, cache_path)
image_texture.take_over_path(cache_path)
return image_texture
func _process(delta):
if _current_request == null and _pending_requests.is_empty():
# nothing more to do..
set_process(false)
return
# nothing in progress, so pick the next request
if _current_request == null:
_current_request = _pending_requests.pop_front()
var renderer = _current_request.renderer
_root.add_child(renderer)
renderer.render(_current_request.input)
await get_tree().process_frame
var actual_size = renderer.get_rect().size
var scale = float(_current_request.height) / float(actual_size.y)
_root.scale = Vector2.ONE * scale
_sub_viewport.size = actual_size * scale
_sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
# give the renderer some time to update itself. 3 frames seem
# to work nicely and keep things speedy.
await get_tree().process_frame
await get_tree().process_frame
await get_tree().process_frame
_fetch_image = true
return
# fetch the image after the renderer is done
if _fetch_image:
# we're done. make a copy of the viewport texture
var image:Image = _scene_holder.texture.get_image()
_current_request.result = image
_current_request.done.emit()
_current_request = null
# remove the renderer
_root.remove_child(_root.get_child(0))
_sub_viewport.render_target_update_mode = SubViewport.UPDATE_DISABLED
_fetch_image = false
class Job:
signal done()
var height:int
var input:GUIDEInput
var renderer:GUIDEIconRenderer
var result:Image

View File

@ -0,0 +1 @@
uid://dq6cdbdturmel

View File

@ -0,0 +1,24 @@
[gd_scene load_steps=3 format=3 uid="uid://8thurteeibtu"]
[ext_resource type="Script" path="res://addons/guide/ui/icon_maker/icon_maker.gd" id="1_hdbjk"]
[sub_resource type="ViewportTexture" id="ViewportTexture_kra7t"]
viewport_path = NodePath("SubViewport")
[node name="GUIDEIconMaker" type="Node2D"]
script = ExtResource("1_hdbjk")
[node name="SubViewport" type="SubViewport" parent="."]
unique_name_in_owner = true
transparent_bg = true
gui_disable_input = true
gui_snap_controls_to_pixels = false
[node name="Root" type="Node2D" parent="SubViewport"]
unique_name_in_owner = true
scale = Vector2(0.1, 0.1)
[node name="SceneHolder" type="Sprite2D" parent="."]
unique_name_in_owner = true
visible = false
texture = SubResource("ViewportTexture_kra7t")