public VisitStatus Visit <TContainer, TValue>(Property <TContainer, TValue> property, ref TContainer container, ref TValue value) { if (!RuntimeTypeInfoCache <TValue> .CanBeNull || null != value) { return(VisitStatus.Unhandled); } if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TValue))) { return(VisitStatus.Unhandled); } if (!property.IsReadOnly && property.HasAttribute <CreateInstanceOnInspectionAttribute>() && !(property is ICollectionElementProperty)) { var attribute = property.GetAttribute <CreateInstanceOnInspectionAttribute>(); if (null == attribute.Type) { if (TypeConstruction.CanBeConstructed <TValue>()) { value = TypeConstruction.Construct <TValue>(); property.SetValue(ref container, value); return(VisitStatus.Unhandled); } Debug.LogWarning(PropertyChecks.GetNotConstructableWarningMessage(typeof(TValue))); } else { var isAssignable = typeof(TValue).IsAssignableFrom(attribute.Type); var isConstructable = TypeConstruction.GetAllConstructableTypes(typeof(TValue)) .Contains(attribute.Type); if (isAssignable && isConstructable) { value = TypeConstruction.Construct <TValue>(attribute.Type); property.SetValue(ref container, value); return(VisitStatus.Unhandled); } Debug.LogWarning(isAssignable ? PropertyChecks.GetNotConstructableWarningMessage(attribute.Type) : PropertyChecks.GetNotAssignableWarningMessage(attribute.Type, typeof(TValue))); } } Visitor.AddToPath(property); try { var path = Visitor.GetCurrentPath(); var element = new NullElement <TValue>(VisitorContext.Root, property, path); VisitorContext.Parent.contentContainer.Add(element); } finally { Visitor.RemoveFromPath(property); } return(VisitStatus.Stop); }
public NullElement(PropertyElement root, IProperty property, PropertyPath path) { m_PotentialTypes = new List <Type> { typeof(Null) }; binding = this; m_Root = root; m_Path = path; name = m_Path.ToString(); TypeConstruction.GetAllConstructableTypes <T>(m_PotentialTypes); if (typeof(T).IsArray) { Resources.Templates.NullStringField.Clone(this); this.Q <Label>().text = GuiFactory.GetDisplayName(property); var button = this.Q <Button>(); button.text = $"Null ({GetTypeName(typeof(T))})"; button.clickable.clicked += ReloadWithArrayType; if (property.IsReadOnly) { button.SetEnabledSmart(false); } return; } if (m_PotentialTypes.Count == 2) { Resources.Templates.NullStringField.Clone(this); this.Q <Label>().text = GuiFactory.GetDisplayName(property); var button = this.Q <Button>(); button.text = $"Null ({GetTypeName(typeof(T))})"; button.clickable.clicked += ReloadWithFirstType; if (property.IsReadOnly) { button.SetEnabledSmart(false); } return; } var typeSelector = new PopupField <Type>( GuiFactory.GetDisplayName(property), m_PotentialTypes, typeof(Null), GetTypeName, GetTypeName); typeSelector.RegisterValueChangedCallback(OnCreateItem); if (property.IsReadOnly) { typeSelector.pickingMode = PickingMode.Ignore; typeSelector.Q(className: UssClasses.Unity.BasePopupFieldInput).SetEnabledSmart(false); } Add(typeSelector); }
public void GettingAllConstructableTypes_FromType_ReturnsProperCount() { var types = new List <Type>(); TypeConstruction.GetAllConstructableTypes(typeof(Types.NotConstructableBaseClass), types); Assert.That(types.Count, Is.EqualTo(4)); types.Clear(); TypeConstruction.GetAllConstructableTypes(typeof(Types.A), types); Assert.That(types.Count, Is.EqualTo(1)); types.Clear(); TypeConstruction.GetAllConstructableTypes(typeof(Types.NotConstructableDerivedClass), types); Assert.That(types.Count, Is.EqualTo(0)); }