using System; using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Text; using System.Threading.Tasks; using NLog; using Spine.Implementations; using Spine.Interfaces.Attachments; namespace Spine.Interfaces { /// /// 应当继承该类实现多版本, 子类需要提供签名为 的构造函数 /// public abstract class SpineObjectData : Utils.ImplementationResolver, ISpineObjectData, IDisposable { protected static readonly Logger _logger = LogManager.GetCurrentClassLogger(); /// /// 构建版本对象 /// public static SpineObjectData New(SpineVersion version, string skelPath, string atlasPath, TextureLoader textureLoader) => CreateInstance(version.Tag, skelPath, atlasPath, textureLoader); /// /// 构造函数, 继承的子类应当实现一个相同签名的构造函数 /// public SpineObjectData(string skelPath, string atlasPath, TextureLoader textureLoader) { } public abstract string SkeletonVersion { get; } public abstract ImmutableArray Skins { get; } public abstract FrozenDictionary SkinsByName { get; } public abstract FrozenDictionary> SlotAttachments { get; } public abstract ImmutableArray Animations { get; } public abstract FrozenDictionary AnimationsByName { get; } public abstract float DefaultMix { get; set; } /// /// 释放纹理资源 /// protected abstract void DisposeAtlas(); /// /// 创建 skeleton /// /// public abstract ISkeleton CreateSkeleton(); /// /// 创建 animationState /// public abstract IAnimationState CreateAnimationState(); /// /// 创建 skeletonClipping /// public abstract ISkeletonClipping CreateSkeletonClipping(); /// /// 创建空皮肤 /// public abstract ISkin CreateSkin(string name); #region IDispose 接口实现 /// /// 引用计数, 初始为 1, 每调用一次 Dispose 会减 1, 由于可能被多个实例同时引用, 因此直到小于等于 0 才会真正释放资源 /// private int _refCount = 1; /// /// 增加引用计数, 当使用同一份数据创建实例副本时, 调用方负责使用该方法增加引用计数, 并且使用 Dispose 或者 Finalize 减少引用计数, 初始为 1 /// public void IncRef() => _refCount++; protected virtual void Dispose(bool disposing) { if (_refCount <= 0) return; _refCount--; if (_refCount <= 0) { if (disposing) { DisposeAtlas(); } } } ~SpineObjectData() { Dispose(false); } public void Dispose() { Dispose(true); if (_refCount <= 0) { GC.SuppressFinalize(this); } } #endregion } }