using System; using System.Collections; using System.Collections.Generic; using System.Linq; using AYellowpaper.SerializedCollections; using BITKit; using UnityEngine; using UnityEngine.Pool; using UnityEngine.UIElements; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; #if UNITY_EDITOR using UnityEditor; #endif namespace Net.BITKit.BitMask { public class ScriptableBitMask : ScriptableObject,ISerializationCallbackReceiver { [SerializeField] public ScriptableImplements implements; internal readonly Dictionary> Dictionary=new(); [SerializeField] public string yaml; public Type Type => implements.Type; public Type[] Types => implements ? implements.Types : Array.Empty(); private void OnEnable() { OnBeforeSerialize(); } public void OnBeforeSerialize() { if(string.IsNullOrEmpty(yaml))return; var deserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) // 驼峰命名 .Build(); Dictionary.Clear(); var newDictionary = deserializer.Deserialize>>(yaml); foreach (var pair in newDictionary) { Dictionary[pair.Key] = pair.Value; } } public void OnAfterDeserialize() { if(Dictionary.Count is 0)return; var serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .Build(); yaml = serializer.Serialize(Dictionary); } public IDictionary> FlagMask { get { var typeDictionary = implements.Types.ToDictionary(x => x.Name, x => x); var nextDictionary = new Dictionary>(); foreach (var (key, d) in Dictionary) { if (typeDictionary.TryGetValue(key, out var type) is false) continue; var hashSet = new HashSet(); foreach (var x in d) { if(typeDictionary.TryGetValue(x,out var t1) is false)continue; hashSet.Add(t1); } nextDictionary[type]=hashSet; } foreach (var type in Types) { if (nextDictionary.TryAdd(type, new HashSet())) ; } return nextDictionary; } } } #if UNITY_EDITOR [CustomEditor(typeof(ScriptableBitMask),true)] public sealed class ScriptableBitMaskEditor:Editor { private const int CellSize = 24; public override VisualElement CreateInspectorGUI() { if (serializedObject.targetObject is not ScriptableBitMask scriptableBitMask) return base.CreateInspectorGUI(); var inspector = new VisualElement { style = { flexDirection = FlexDirection.Column } }; var defaultPropertyFields = inspector.Create(); BITInspectorExtensions.FillDefaultInspector(defaultPropertyFields.Create(),serializedObject,false); var root = inspector.Create(); root.style.flexDirection = new StyleEnum(FlexDirection.Row); var allFlags = scriptableBitMask.Types; var labelRow = root.Create(); var toggleRot = root.Create(); labelRow.style.alignSelf = new StyleEnum(Align.FlexEnd); for (var x = -1; x < allFlags.Length; x++) { if (x is -1) { var container = toggleRot.Create(); container.style.flexDirection = FlexDirection.Row; foreach (var type in scriptableBitMask.Types.Reverse()) { var text = container.Create