public override void Initialize() { base.Initialize(); // figure out which fields and properties are useful to add to the inspector IEnumerable <FieldInfo> fields = ReflectionUtils.GetFields(_valueType); foreach (FieldInfo field in fields) { if (!field.IsPublic && !field.IsDefined(typeof(InspectableAttribute))) { continue; } AbstractTypeInspector inspector = TypeInspectorUtils.GetInspectorForType(field.FieldType, _target, field); if (inspector != null) { inspector.SetStructTarget(_target, this, field); inspector.Initialize(); _inspectors.Add(inspector); } } IEnumerable <PropertyInfo> properties = ReflectionUtils.GetProperties(_valueType); foreach (PropertyInfo prop in properties) { if (!prop.CanRead || !prop.CanWrite) { continue; } bool isPropertyUndefinedOrPublic = !prop.CanWrite || (prop.CanWrite && prop.SetMethod.IsPublic); if ((!prop.GetMethod.IsPublic || !isPropertyUndefinedOrPublic) && !prop.IsDefined(typeof(InspectableAttribute))) { continue; } AbstractTypeInspector inspector = TypeInspectorUtils.GetInspectorForType(prop.PropertyType, _target, prop); if (inspector != null) { inspector.SetStructTarget(_target, this, prop); inspector.Initialize(); _inspectors.Add(inspector); } } }
/// <summary> /// this version will first fetch the struct before getting/setting values on it when invoking the getter/setter /// </summary> /// <returns>The struct target.</returns> /// <param name="target">Target.</param> /// <param name="structName">Struct name.</param> /// <param name="field">Field.</param> public void setStructTarget(object target, AbstractTypeInspector parentInspector, FieldInfo field) { _target = target; _memberInfo = field; _name = field.Name; _valueType = field.FieldType; _getter = () => { var structValue = parentInspector.getValue(); return(field.GetValue(structValue)); }; _setter = (val) => { var structValue = parentInspector.getValue(); field.SetValue(structValue, val); parentInspector.setValue(structValue); }; }
/// <summary> /// this version will first fetch the struct before getting/setting values on it when invoking the getter/setter /// </summary> /// <returns>The struct target.</returns> /// <param name="target">Target.</param> /// <param name="structName">Struct name.</param> /// <param name="field">Field.</param> public void setStructTarget(object target, AbstractTypeInspector parentInspector, PropertyInfo prop) { _target = target; _memberInfo = prop; _name = prop.Name; _valueType = prop.PropertyType; _getter = () => { var structValue = parentInspector.getValue(); return(ReflectionUtils.getPropertyGetter(prop).Invoke(structValue, null)); }; _setter = (val) => { var structValue = parentInspector.getValue(); prop.SetValue(structValue, val); parentInspector.setValue(structValue); }; }
/// <summary> /// this version will first fetch the struct before getting/setting values on it when invoking the getter/setter /// </summary> /// <returns>The struct target.</returns> /// <param name="target">Target.</param> /// <param name="structName">Struct name.</param> /// <param name="field">Field.</param> public void SetStructTarget(object target, AbstractTypeInspector parentInspector, PropertyInfo prop) { _target = target; _memberInfo = prop; _name = prop.Name; _valueType = prop.PropertyType; _isReadOnly = !prop.CanWrite || parentInspector._isReadOnly; _getter = obj => { object structValue = parentInspector.GetValue(); return(ReflectionUtils.GetPropertyGetter(prop).Invoke(structValue, null)); }; if (!_isReadOnly) { _setter = (val) => { object structValue = parentInspector.GetValue(); prop.SetValue(structValue, val); parentInspector.SetValue(structValue); }; } }
/// <summary> /// this version will first fetch the struct before getting/setting values on it when invoking the getter/setter /// </summary> /// <returns>The struct target.</returns> /// <param name="target">Target.</param> /// <param name="structName">Struct name.</param> /// <param name="field">Field.</param> public void SetStructTarget(object target, AbstractTypeInspector parentInspector, FieldInfo field) { _target = target; _memberInfo = field; _name = field.Name; _valueType = field.FieldType; _isReadOnly = field.IsInitOnly || parentInspector._isReadOnly; _getter = obj => { object structValue = parentInspector.GetValue(); return(field.GetValue(structValue)); }; if (!_isReadOnly) { _setter = val => { object structValue = parentInspector.GetValue(); field.SetValue(structValue, val); parentInspector.SetValue(structValue); }; } }
/// <summary> /// fetches all the relevant AbstractTypeInspectors for target including fields, properties and methods. /// </summary> /// <param name="target"></param> /// <returns></returns> public static List <AbstractTypeInspector> GetInspectableProperties(object target) { List <AbstractTypeInspector> inspectors = new List <AbstractTypeInspector>(); Type targetType = target.GetType(); bool isComponentSubclass = target is Component; IEnumerable <FieldInfo> fields = ReflectionUtils.GetFields(targetType); foreach (FieldInfo field in fields) { if (field.IsStatic || field.IsDefined(notInspectableAttrType)) { continue; } bool hasInspectableAttribute = field.IsDefined(inspectableAttrType); // private fields must have the InspectableAttribute if (!field.IsPublic && !hasInspectableAttribute) { continue; } // similarly, readonly fields must have the InspectableAttribute if (field.IsInitOnly && !hasInspectableAttribute) { continue; } // skip enabled and entity which is handled elsewhere if this is a Component if (isComponentSubclass && (field.Name == "Enabled" || field.Name == "Entity")) { continue; } AbstractTypeInspector inspector = GetInspectorForType(field.FieldType, target, field); if (inspector != null) { inspector.SetTarget(target, field); inspector.Initialize(); inspectors.Add(inspector); } } IEnumerable <PropertyInfo> properties = ReflectionUtils.GetProperties(targetType); foreach (PropertyInfo prop in properties) { if (prop.IsDefined(notInspectableAttrType)) { continue; } // Transforms and Component subclasses arent useful to inspect if (prop.PropertyType == transformType || prop.PropertyType.IsSubclassOf(componentType)) { continue; } if (!prop.CanRead || prop.GetGetMethod(true).IsStatic) { continue; } bool hasInspectableAttribute = prop.IsDefined(inspectableAttrType); // private props must have the InspectableAttribute if (!prop.GetMethod.IsPublic && !hasInspectableAttribute) { continue; } // similarly, readonly props must have the InspectableAttribute if (!prop.CanWrite && !hasInspectableAttribute) { continue; } // skip Component.enabled and entity which is handled elsewhere if (isComponentSubclass && (prop.Name == "Enabled" || prop.Name == "Entity")) { continue; } AbstractTypeInspector inspector = GetInspectorForType(prop.PropertyType, target, prop); if (inspector != null) { inspector.SetTarget(target, prop); inspector.Initialize(); inspectors.Add(inspector); } } IEnumerable <MethodInfo> methods = GetAllMethodsWithAttribute <InspectorCallableAttribute>(targetType); foreach (MethodInfo method in methods) { if (!MethodInspector.AreParametersValid(method.GetParameters())) { continue; } MethodInspector inspector = new MethodInspector(); inspector.SetTarget(target, method); inspector.Initialize(); inspectors.Add(inspector); } return(inspectors); }