public Button(string methodName) { InspectedMethod foundMethod = null; foreach (var method in InspectedType.Get(typeof(T)).GetMethods(InspectedMemberFilters.All)) { if (method.Method.Name == methodName) { foundMethod = method; } } if (foundMethod != null) { _label = (fiGUIContent)foundMethod.DisplayLabel; _enabled = true; _onClick = (o, c) => foundMethod.Invoke(o); } else { Debug.LogError("Unable to find method " + methodName + " on " + typeof(T).CSharpName()); _label = new fiGUIContent(methodName + " (unable to find on " + typeof(T).CSharpName() + ")"); _enabled = false; _onClick = (o, c) => { }; } }
/// <summary> /// Initializes a new instance of the TypeMetadata class from a type. Use TypeCache to get /// instances of TypeMetadata; do not use this constructor directly. /// </summary> internal InspectedType(Type type) { ReflectedType = type; // determine if we are a collection or array; recall that arrays implement the // ICollection interface, however _isArray = type.IsArray; IsCollection = _isArray || type.IsImplementationOf(typeof(ICollection <>)); // We're not a collection, so lookup the properties on this type if (IsCollection == false) { _cachedMembers = new Dictionary <IInspectedMemberFilter, List <InspectedMember> >(); _cachedProperties = new Dictionary <IInspectedMemberFilter, List <InspectedProperty> >(); _cachedMethods = new Dictionary <IInspectedMemberFilter, List <InspectedMethod> >(); _allMembers = new List <InspectedMember>(); // Add the parent members first. They will be sorted properly and the like. if (ReflectedType.Resolve().BaseType != null) { var inspectedParentType = InspectedType.Get(ReflectedType.Resolve().BaseType); _allMembers.AddRange(inspectedParentType._allMembers); } // Add local properties. var localMembers = CollectUnorderedLocalMembers(type).ToList(); StableSort(localMembers, (a, b) => { return(Math.Sign(InspectorOrderAttribute.GetInspectorOrder(a.MemberInfo) - InspectorOrderAttribute.GetInspectorOrder(b.MemberInfo))); }); _allMembers.AddRange(localMembers); // Add our property names in _nameToProperty = new Dictionary <string, InspectedProperty>(); _formerlySerializedAsPropertyNames = new Dictionary <string, InspectedProperty>(); foreach (var member in _allMembers) { if (member.IsProperty == false) { continue; } if (fiSettings.EmitWarnings && _nameToProperty.ContainsKey(member.Name)) { Debug.LogWarning("Duplicate property with name=" + member.Name + " detected on " + ReflectedType.CSharpName()); } _nameToProperty[member.Name] = member.Property; foreach (FormerlySerializedAsAttribute attr in member.MemberInfo.GetCustomAttributes(typeof(FormerlySerializedAsAttribute), /*inherit:*/ true)) { _nameToProperty[attr.oldName] = member.Property; } } } }
void tkIControl.InitializeId(ref int nextId) { _uniqueId = nextId++; foreach (var control in NonMemberChildControls) { control.InitializeId(ref nextId); } var type = GetType(); while (type != null) { var inspectedMembers = InspectedType.Get(type).GetMembers(InspectedMemberFilters.TkControlMembers); foreach (InspectedMember member in inspectedMembers) { var memberType = member.Property.StorageType; if (typeof(tkIControl).IsAssignableFrom(memberType)) { tkIControl control; if (TryReadValue(member, this, out control) == false) { continue; } if (control == null) { continue; } control.InitializeId(ref nextId); } //this is a redundant check, since this is sure to be compatible with IEnumerable (because of our filter) //But, since this reads better, it is kept. else if (typeof(IEnumerable <tkIControl>).IsAssignableFrom(memberType)) { IEnumerable <tkIControl> controls; if (TryReadValue(member, this, out controls) == false) { continue; } if (controls == null) { continue; } foreach (var control in controls) { control.InitializeId(ref nextId); } } } type = type.Resolve().BaseType; } }
public override float GetElementHeight(GUIContent label, Facade <T> element, fiGraphMetadata metadata) { float height = 0; if (string.IsNullOrEmpty(label.text) == false || TypeOptions.Types.Length > 1) { height = LabelHeight; } var anim = metadata.GetMetadata <fiAnimationMetadata>(); if (anim.IsAnimating) { return(height + anim.AnimationHeight); } if (element == null) { element = new Facade <T>(); } if (element.InstanceType == null) { element.InstanceType = TypeOptions.Types[0]; } InspectedType inspectedType = InspectedType.Get(element.InstanceType); var serializer = (BaseSerializer)fiSingletons.Get(fiInstalledSerializerManager.DefaultMetadata.SerializerType); var deserializationOp = new ListSerializationOperator() { SerializedObjects = element.ObjectReferences }; var properties = inspectedType.GetProperties(InspectedMemberFilters.InspectableMembers); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; object propertyValue = DeserializeProperty(serializer, deserializationOp, property, element); height += fiEditorGUI.EditPropertyHeightDirect(property, propertyValue, metadata.Enter(property.Name)); height += SplitterHeight; } return(height); }
public static void Add(ref IList list, Type elementType) { if (list.GetType().IsArray) { Array arr = Array.CreateInstance(elementType, list.Count + 1); for (int i = 0; i < list.Count; ++i) { arr.SetValue(list[i], i); } list = arr; } else { UnityEngine.Debug.Log("Adding " + elementType + " to " + list); list.Add(InspectedType.Get(elementType).CreateInstance()); } }
private void InitializeFromMemberName(string memberName) { var property = InspectedType.Get(typeof(T)).GetPropertyByName(memberName); if (property == null) { _errorMessage = "Unable to locate member `" + memberName + "` on type `" + typeof(T).CSharpName() + "`"; _fieldType = typeof(T); _attributes = null; _getValue = (o, c) => default(T); _setValue = (o, c, v) => { }; _label = memberName + " (unable to locate)"; return; } _fieldType = property.StorageType; _attributes = property.MemberInfo; _getValue = (o, c) => property.Read(o); _setValue = (o, c, v) => property.Write(o, v); _label = property.DisplayName; }
/// <summary> /// Attempts to remove the property with the given name. /// </summary> /// <param name="propertyName"> /// The name of the property to remove. /// </param> public static void RemoveProperty <T>(string propertyName) { var type = InspectedType.Get(typeof(T)); type._nameToProperty.Remove(propertyName); // reset all filter caches type._cachedMembers = new Dictionary <IInspectedMemberFilter, List <InspectedMember> >(); type._cachedMethods = new Dictionary <IInspectedMemberFilter, List <InspectedMethod> >(); type._cachedProperties = new Dictionary <IInspectedMemberFilter, List <InspectedProperty> >(); // remove it from _allmembers for (int i = 0; i < type._allMembers.Count; ++i) { var member = type._allMembers[i]; if (propertyName == member.Name) { type._allMembers.RemoveAt(i); break; } } }
/// <summary> /// Populate an pre-constructed instance with the data stored inside of the facade. /// </summary> /// <param name="instance">The object instance to populate.</param> public void PopulateInstance(ref T instance) { if (instance.GetType() != InstanceType) { Debug.LogWarning("PopulateInstance: Actual Facade type is different " + "(instance.GetType() = " + instance.GetType().CSharpName() + ", InstanceType = " + InstanceType.CSharpName() + ")"); } Type defaultSerializer = fiInstalledSerializerManager.DefaultMetadata.SerializerType; var serializer = (BaseSerializer)fiSingletons.Get(defaultSerializer); var serializationOperator = new ListSerializationOperator() { SerializedObjects = ObjectReferences }; InspectedType inspectedType = InspectedType.Get(instance.GetType()); foreach (var tuple in FacadeMembers) { string name = tuple.Key; InspectedProperty property = inspectedType.GetPropertyByName(name); if (property != null) { try { object deserializedMember = serializer.Deserialize( property.StorageType.Resolve(), tuple.Value, serializationOperator); property.Write(instance, deserializedMember); } catch (Exception e) { Debug.LogError("Skipping property " + name + " in facade due to " + "deserialization exception.\n" + e); } } } }
public override Facade <T> Edit(Rect region, GUIContent label, Facade <T> element, fiGraphMetadata metadata) { if (element == null) { element = new Facade <T>(); } if (element.InstanceType == null) { element.InstanceType = TypeOptions.Types[0]; } bool changedTypes; DrawHeader(ref region, label, element, out changedTypes); var facadeMembers = new Dictionary <string, string>(); var facadeReferences = new List <UnityObject>(); InspectedType inspectedType = InspectedType.Get(element.InstanceType); var serializer = (BaseSerializer)fiSingletons.Get(fiInstalledSerializerManager.DefaultMetadata.SerializerType); var deserializationOp = new ListSerializationOperator() { SerializedObjects = element.ObjectReferences }; var serializationOp = new ListSerializationOperator() { SerializedObjects = facadeReferences }; float usedHeight = 0; var anim = metadata.GetMetadata <fiAnimationMetadata>(); if (anim.IsAnimating) { fiEditorGUI.BeginFadeGroupHeight(LabelHeight, ref region, anim.AnimationHeight); fiEditorUtility.RepaintAllEditors(); } var properties = inspectedType.GetProperties(InspectedMemberFilters.InspectableMembers); for (int i = 0; i < properties.Count; ++i) { InspectedProperty property = properties[i]; object propertyValue = DeserializeProperty(serializer, deserializationOp, property, element); float height = fiEditorGUI.EditPropertyHeightDirect(property, propertyValue, metadata.Enter(property.Name)); Rect propertyRect = region; propertyRect.height = height; region.y += height; region.y += SplitterHeight; usedHeight += height + SplitterHeight; object updatedValue = fiEditorGUI.EditPropertyDirect(propertyRect, property, propertyValue, metadata.Enter(property.Name)); string data; if (TrySerializeProperty(serializer, serializationOp, property, updatedValue, out data)) { facadeMembers[property.Name] = data; } } if (anim.IsAnimating) { fiEditorGUI.EndFadeGroup(); } element.FacadeMembers = facadeMembers; element.ObjectReferences = facadeReferences; if (changedTypes && anim.UpdateHeight(usedHeight)) { fiEditorUtility.RepaintAllEditors(); } return(element); }