Files
stickman/scripts/thumbnails/thumbnail_cache.gd
ryan b66ded5f60 Add headless regression tests for Prop Editor functionality
- Implement tests for PropFile, including preset conversion, file dictionary conversion, round-trip serialization, version rejection, default values for missing keys, flattening, sanitization, and save/load functionality.
- Create tests for PropEditor, covering window title formatting, mode button text, safe saving, and recent file list management.
- Add tests for PropTheme, validating fallback behavior, invalid input handling, and default values for primitives and UI tokens.
- Introduce tests for ThumbnailCache, ensuring proper key formatting, PNG handling, and behavior with missing files.
2026-09-19 21:26:03 -04:00

93 lines
2.4 KiB
GDScript

class_name ThumbnailCache
extends RefCounted
const STICKMEN_DIR := "user://thumbnails/stickmen"
const PROP_DIR := "user://thumbnails/props"
const PROP_VERSION := 1
var _memory: Dictionary = {}
func get_texture(cache_path: String) -> Texture2D:
if _memory.has(cache_path):
return _memory[cache_path] as Texture2D
var texture: Texture2D = load_png(cache_path)
if texture != null:
_memory[cache_path] = texture
return texture
func store_texture(cache_path: String, texture: Texture2D) -> Error:
if texture == null:
return ERR_INVALID_PARAMETER
_memory[cache_path] = texture
return save_png(texture, cache_path)
func forget_memory(cache_path: String) -> void:
_memory.erase(cache_path)
func clear_memory() -> void:
_memory.clear()
func stickman_key(path: String) -> String:
return "%s_%d" % [path.get_file().get_basename(), FileAccess.get_modified_time(path)]
func stickman_png(key: String) -> String:
return STICKMEN_DIR + "/" + key + ".png"
func prop_png(id: String) -> String:
return PROP_DIR + "/" + id + "_v" + str(PROP_VERSION) + ".png"
func prop_file_key(path: String) -> String:
return "%s_%d" % [path.get_file().get_basename(), FileAccess.get_modified_time(path)]
func prop_file_png(path: String) -> String:
return PROP_DIR + "/" + prop_file_key(path) + ".png"
func load_png(png_path: String) -> Texture2D:
if _memory.has(png_path):
return _memory[png_path] as Texture2D
if not FileAccess.file_exists(png_path):
return null
var img := Image.load_from_file(png_path)
if img == null:
return null
var texture: Texture2D = ImageTexture.create_from_image(img)
_memory[png_path] = texture
return texture
func save_png(tex: Texture2D, png_path: String) -> Error:
if tex == null:
return ERR_INVALID_PARAMETER
var img := tex.get_image()
if img == null:
return ERR_CANT_CREATE
ensure_dir(png_path.get_base_dir())
_memory[png_path] = tex
return img.save_png(png_path)
func ensure_dir(dir: String) -> void:
DirAccess.make_dir_recursive_absolute(dir)
func clean_stale_stickmen(valid_keys: Dictionary) -> void:
if not DirAccess.dir_exists_absolute(STICKMEN_DIR):
return
var dir := DirAccess.open(STICKMEN_DIR)
if dir == null:
return
dir.list_dir_begin()
var fname := dir.get_next()
while fname != "":
if not dir.current_is_dir() and fname.ends_with(".png"):
var key := fname.trim_suffix(".png")
if not valid_keys.has(key):
DirAccess.remove_absolute(STICKMEN_DIR + "/" + fname)
fname = dir.get_next()
dir.list_dir_end()