From 6f032bdd057034c1a39fff7616ebd44dc246790a Mon Sep 17 00:00:00 2001 From: ww-rm Date: Sat, 5 Apr 2025 10:10:04 +0800 Subject: [PATCH] optimize --- SpineViewer/Spine/AnimationTracks.cs | 41 ++++++++++++++++++++-------- SpineViewer/Spine/Spine.cs | 2 +- SpineViewer/Spine/TypeConverter.cs | 10 +++---- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/SpineViewer/Spine/AnimationTracks.cs b/SpineViewer/Spine/AnimationTracks.cs index c712061..ec8c47c 100644 --- a/SpineViewer/Spine/AnimationTracks.cs +++ b/SpineViewer/Spine/AnimationTracks.cs @@ -46,14 +46,12 @@ namespace SpineViewer.Spine /// /// 轨道属性描述符, 实现对属性的读取和赋值 /// - /// 关联的 Spine 对象 /// 轨道索引 - public class TrackWrapperPropertyDescriptor(Spine spine, int i) : PropertyDescriptor($"Track{i}", [new DisplayNameAttribute($"轨道 {i}")]) + public class TrackWrapperPropertyDescriptor(int i) : PropertyDescriptor($"Track{i}", [new DisplayNameAttribute($"轨道 {i}")]) { - private readonly Spine spine = spine; private readonly int idx = i; - public override Type ComponentType => typeof(AnimationTracksType); + public override Type ComponentType => typeof(AnimationTracks); public override bool IsReadOnly => false; public override Type PropertyType => typeof(TrackWrapper); public override bool CanResetValue(object component) => false; @@ -63,14 +61,23 @@ namespace SpineViewer.Spine /// /// 得到一个轨道包装类, 允许用户查看或者修改具体的属性值, 这个地方决定了在面板上看到的是一个对象及其属性 /// - public override object? GetValue(object? component) => new TrackWrapper(spine, idx); + public override object? GetValue(object? component) + { + if (component is AnimationTracks tracks) + return tracks.GetTrackWrapper(idx); + return null; + } /// /// 允许通过字符串赋值修改该轨道的动画, 这里决定了当其他地方的调用 (比如 Converter) 通过 value 来设置属性值的时候应该怎么处理 /// public override void SetValue(object? component, object? value) { - if (value is string s) spine.SetAnimation(idx, s); + if (component is AnimationTracks tracks) + { + if (value is string s) + tracks.Spine.SetAnimation(idx, s); // tracks.SetTrackWrapper(idx, s); + } } } @@ -78,10 +85,12 @@ namespace SpineViewer.Spine /// AnimationTracks 动态类型包装类, 用于提供对 Spine 对象多轨道动画的访问能力, 不同轨道将动态生成属性 /// /// 关联的 Spine 对象 - public class AnimationTracksType(Spine spine) : ICustomTypeDescriptor + public class AnimationTracks(Spine spine) : ICustomTypeDescriptor { - private readonly Dictionary pdCache = []; + private static readonly Dictionary pdCache = []; + public Spine Spine { get; } = spine; + private readonly Dictionary trackWrapperProperties = []; // XXX: 必须实现 ICustomTypeDescriptor 接口, 不能继承 CustomTypeDescriptor, 似乎继承下来的东西会有问题, 导致某些调用不正确 @@ -102,12 +111,22 @@ namespace SpineViewer.Spine foreach (var i in Spine.GetTrackIndices()) { if (!pdCache.ContainsKey(i)) - pdCache[i] = new TrackWrapperPropertyDescriptor(Spine, i); + pdCache[i] = new TrackWrapperPropertyDescriptor(i); props.Add(pdCache[i]); } return new PropertyDescriptorCollection(props.ToArray()); } + /// + /// 访问 TrackWrapper 属性 AnimationTracks.Track{i} + /// + public TrackWrapper GetTrackWrapper(int i) + { + if (!trackWrapperProperties.ContainsKey(i)) + trackWrapperProperties[i] = new TrackWrapper(Spine, i); + return trackWrapperProperties[i]; + } + /// /// 在属性面板悬停可以按轨道顺序显示动画名称 /// @@ -115,10 +134,10 @@ namespace SpineViewer.Spine public override bool Equals(object? obj) { - if (obj is AnimationTracksType tracks) return ToString() == tracks.ToString(); + if (obj is AnimationTracks tracks) return ToString() == tracks.ToString(); return base.Equals(obj); } - public override int GetHashCode() => (typeof(AnimationTracksType).FullName + ToString()).GetHashCode(); + public override int GetHashCode() => (typeof(AnimationTracks).FullName + ToString()).GetHashCode(); } } diff --git a/SpineViewer/Spine/Spine.cs b/SpineViewer/Spine/Spine.cs index e72d863..43f9bed 100644 --- a/SpineViewer/Spine/Spine.cs +++ b/SpineViewer/Spine/Spine.cs @@ -242,7 +242,7 @@ namespace SpineViewer.Spine [Editor(typeof(AnimationTracksEditor), typeof(UITypeEditor))] [TypeConverter(typeof(ExpandableObjectConverter))] [Category("[3] 动画"), DisplayName("多轨道动画管理")] - public AnimationTracksType AnimationTracks { get; private set; } + public AnimationTracks AnimationTracks { get; private set; } /// /// 包含的所有皮肤名称 diff --git a/SpineViewer/Spine/TypeConverter.cs b/SpineViewer/Spine/TypeConverter.cs index e4b5114..c3e45d9 100644 --- a/SpineViewer/Spine/TypeConverter.cs +++ b/SpineViewer/Spine/TypeConverter.cs @@ -89,14 +89,14 @@ namespace SpineViewer.Spine public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) { - if (context.Instance is AnimationTracksType animTrack) + if (context.Instance is AnimationTracks tracks) { - return new StandardValuesCollection(animTrack.Spine.AnimationNames); + return new StandardValuesCollection(tracks.Spine.AnimationNames); } - else if (context.Instance is object[] instances && instances.All(x => x is AnimationTracksType)) + else if (context.Instance is object[] instances && instances.All(x => x is AnimationTracks)) { - // XXX: 这里不知道为啥总是会得到 object[] 类型而不是具体的 AnimationTracksType[] 类型 - var animTracks = instances.Cast().ToArray(); + // XXX: 这里不知道为啥总是会得到 object[] 类型而不是具体的类型 + var animTracks = instances.Cast().ToArray(); if (animTracks.Length > 0) { IEnumerable common = animTracks[0].Spine.AnimationNames;