Files
2025-11-30 08:35:03 +02:00

142 lines
3.3 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityGLTF.Cache
{
/// <summary>
/// A ref-counted cache data object containing lists of Unity objects that were created for the sake of a GLTF scene/node.
/// This supports counting the amount of refcounts that will dispose of itself
/// </summary>
public class RefCountedCacheData
{
private bool _isDisposed = false;
/// <summary>
/// Ref count for this cache data.
/// </summary>
/// <remarks>
/// Initialized to 0. When assigning the cache data to an instantiated GLTF
/// object the count will increase.
/// </remarks>
private int _refCount = 0;
private readonly object _refCountLock = new object();
/// <summary>
/// Meshes used by this GLTF node.
/// </summary>
public MeshCacheData[] MeshCache { get; private set; }
/// <summary>
/// Materials used by this GLTF node.
/// </summary>
public MaterialCacheData[] MaterialCache { get; private set; }
/// <summary>
/// Textures used by this GLTF node.
/// </summary>
public TextureCacheData[] TextureCache { get; private set; }
/// <summary>
/// Animations used by this GLTF node.
/// </summary>
public AnimationCacheData[] AnimationCache { get; private set; }
/// <summary>
/// Textures from the AssetCache that might need to be cleaned up
/// </summary>
public Texture2D[] ImageCache { get; private set; }
public RefCountedCacheData(MaterialCacheData[] materialCache, MeshCacheData[] meshCache, TextureCacheData[] textureCache, Texture2D[] imageCache, AnimationCacheData[] animationCache)
{
MaterialCache = materialCache;
MeshCache = meshCache;
TextureCache = textureCache;
ImageCache = imageCache;
AnimationCache = animationCache;
}
public void IncreaseRefCount()
{
if (_isDisposed)
{
throw new InvalidOperationException("Cannot inscrease the ref count on disposed cache data.");
}
lock (_refCountLock)
{
_refCount++;
}
}
public void DecreaseRefCount()
{
if (_isDisposed)
{
throw new InvalidOperationException("Cannot decrease the ref count on disposed cache data.");
}
lock (_refCountLock)
{
if (_refCount <= 0)
{
throw new InvalidOperationException("Cannot decrease the cache data ref count below zero.");
}
_refCount--;
}
if (_refCount <= 0)
{
DestroyCachedData();
}
}
private void DestroyCachedData()
{
// Destroy the cached meshes
for (int i = 0; i < MeshCache.Length; i++)
{
MeshCache[i]?.Dispose();
MeshCache[i] = null;
}
// Destroy the cached textures
for (int i = 0; i < TextureCache.Length; i++)
{
TextureCache[i]?.Dispose();
TextureCache[i] = null;
}
// Destroy the cached materials
for (int i = 0; i < MaterialCache.Length; i++)
{
MaterialCache[i]?.Dispose();
MaterialCache[i] = null;
}
// Destroy the cached images
for (int i = 0; i < ImageCache.Length; i++)
{
if (ImageCache[i] != null)
{
UnityEngine.Object.Destroy(ImageCache[i]);
ImageCache[i] = null;
}
}
// Destroy the cached animations
for (int i = 0; i < AnimationCache.Length; i++)
{
if (AnimationCache[i] != null)
{
UnityEngine.Object.Destroy(AnimationCache[i].LoadedAnimationClip);
AnimationCache[i] = null;
}
}
_isDisposed = true;
}
}
}