Files

58 lines
2.0 KiB
C#
Raw Permalink Normal View History

using Godot;
using System.Collections.Generic;
using System.IO;
namespace Theriapolis.GodotHost.Platform;
/// <summary>
/// Loads PNGs from Content/Gfx as Godot ImageTextures and caches them by
/// relative path. Texture filter is set to Nearest (project default for
/// pixel art).
///
/// This bypasses Godot's res:// import pipeline because Content/ lives
/// outside the project — but for static pixel-art assets at native size
/// the import pipeline doesn't add anything we need.
///
/// Tactical-view tile rendering (M4) will hit this from chunk streamers,
/// so the cache is per-process and never evicted; the full atlas
/// (~50 PNGs at 32x32) is well under 1 MB.
/// </summary>
public static class ContentLoader
{
private static readonly Dictionary<string, ImageTexture> _cache = new();
/// <summary>
/// Loads a PNG from <c>Content/Gfx/&lt;relativePath&gt;</c>. Returns
/// null and logs an error if the file is missing or unreadable.
/// </summary>
public static ImageTexture? LoadGfx(string relativePath)
{
if (_cache.TryGetValue(relativePath, out var cached)) return cached;
string absolute = Path.Combine(ContentPaths.GfxDir, relativePath);
if (!File.Exists(absolute))
{
// Silent miss — callers (e.g. atlas variant probes) treat null
// as "no more variants" and shouldn't generate error noise.
// Genuine missing-asset diagnostics live in AssetTest's summary.
return null;
}
var image = Image.LoadFromFile(absolute);
if (image is null)
{
GD.PrintErr($"[ContentLoader] Image.LoadFromFile failed: {absolute}");
return null;
}
var tex = ImageTexture.CreateFromImage(image);
_cache[relativePath] = tex;
return tex;
}
public static int CacheCount => _cache.Count;
/// <summary>Drops every cached texture. Useful for hot-reload tests.</summary>
public static void ClearCache() => _cache.Clear();
}