class_name AtlasTextureCache extends RefCounted var _textures: Dictionary = {} var _atlases: Dictionary = {} var _frame_regions: Dictionary = {} func get_region(atlas_path: String, region_name: String) -> Texture2D: return get_atlas_texture(atlas_path, TextureRegionCatalog.region_for(atlas_path, region_name)) func get_frame(atlas_path: String, frame_name: String) -> Texture2D: return get_atlas_texture(atlas_path, frame_region(atlas_path, frame_name)) func get_atlas_texture(atlas_path: String, region: Rect2) -> Texture2D: var cache_key := "%s:%s:%s:%s:%s" % [ atlas_path, region.position.x, region.position.y, region.size.x, region.size.y ] if _textures.has(cache_key): return _textures[cache_key] var atlas := _load_atlas(atlas_path) var texture := AtlasTexture.new() texture.atlas = atlas texture.region = region _textures[cache_key] = texture return texture func preload_group(atlas_path: String, region_names: Array[String]) -> void: for region_name in region_names: get_region(atlas_path, region_name) func clear_unused() -> void: _textures.clear() func frame_region(atlas_path: String, frame_name: String) -> Rect2: var catalog := _load_frame_catalog(atlas_path) if catalog.is_empty(): return Rect2(0, 0, 1, 1) var frame = catalog.get(frame_name) if frame == null and not frame_name.ends_with("_png"): frame = catalog.get("%s_png" % frame_name) if not frame is Dictionary: return Rect2(0, 0, 1, 1) return Rect2( float(frame.get("x", 0)), float(frame.get("y", 0)), float(frame.get("w", frame.get("width", 1))), float(frame.get("h", frame.get("height", 1))) ) func _load_atlas(atlas_path: String) -> Texture2D: if _atlases.has(atlas_path): return _atlases[atlas_path] var atlas := load(atlas_path) as Texture2D _atlases[atlas_path] = atlas return atlas func _load_frame_catalog(atlas_path: String) -> Dictionary: if _frame_regions.has(atlas_path): return _frame_regions[atlas_path] var json_path := "%s.json" % atlas_path.get_basename() var file := FileAccess.open(json_path, FileAccess.READ) if file == null: _frame_regions[atlas_path] = {} return {} var parsed = JSON.parse_string(file.get_as_text()) if not parsed is Dictionary: _frame_regions[atlas_path] = {} return {} var frames = parsed.get("frames", {}) if not frames is Dictionary: frames = {} _frame_regions[atlas_path] = frames return frames