using System; using UnityEngine; namespace Unity.VisualScripting { public interface IMemberUnitOption : IUnitOption { Type targetType { get; } Member member { get; } Member pseudoDeclarer { get; } } public abstract class MemberUnitOption : UnitOption, IMemberUnitOption where TMemberUnit : MemberUnit { protected MemberUnitOption() : base() { } protected MemberUnitOption(TMemberUnit unit) : base(unit) { sourceScriptGuids = UnitBase.GetScriptGuids(unit.member.targetType).ToHashSet(); } private Member _member; private Member _pseudoDeclarer; public Member member { get => _member ?? unit.member; set => _member = value; } public Member pseudoDeclarer { get => _pseudoDeclarer ?? member.ToPseudoDeclarer(); set => _pseudoDeclarer = value; } public bool isPseudoInherited => member == pseudoDeclarer; protected abstract ActionDirection direction { get; } public Type targetType { get; private set; } protected override GUIStyle Style() { if (unit.member.isPseudoInherited) { return FuzzyWindow.Styles.optionWithIconDim; } return base.Style(); } protected override string Label(bool human) { return unit.member.info.SelectedName(human, direction); } protected override string FavoriteKey() { return $"{member.ToUniqueString()}@{direction.ToString().ToLower()}"; } protected override int Order() { if (member.isConstructor) { return 0; } return base.Order(); } protected override string Haystack(bool human) { return $"{targetType.SelectedName(human)}{(human ? ": " : ".")}{Label(human)}"; } protected override void FillFromUnit() { targetType = unit.member.targetType; member = unit.member; pseudoDeclarer = member.ToPseudoDeclarer(); base.FillFromUnit(); } public override void Deserialize(UnitOptionRow row) { base.Deserialize(row); targetType = Codebase.DeserializeType(row.tag1); if (!string.IsNullOrEmpty(row.tag2)) { member = Codebase.DeserializeMember(row.tag2); } if (!string.IsNullOrEmpty(row.tag3)) { pseudoDeclarer = Codebase.DeserializeMember(row.tag3); } } public override UnitOptionRow Serialize() { var row = base.Serialize(); row.tag1 = Codebase.SerializeType(targetType); row.tag2 = Codebase.SerializeMember(member); row.tag3 = Codebase.SerializeMember(pseudoDeclarer); return row; } public override void OnPopulate() { // Members are late-reflected to speed up loading and search // We only reflect them when we're just about to populate their node // By doing it in OnPopulate instead of on-demand later, we ensure // any error will be gracefully catched and shown as a warning by // the fuzzy window member.EnsureReflected(); pseudoDeclarer.EnsureReflected(); base.OnPopulate(); } } }