/// <summary> /// Register a reflected property bag which is compatible with scene serialization for the given type /// </summary> /// <param name="type">The type which will be represented by the property bag</param> public static void RegisterPropertyBag(Type type) { if (ReflectedPropertyBagUtils.PropertyBagExists(type)) { return; } if (type.IsGenericTypeDefinition || type.IsAbstract || type.IsInterface) { return; } var propertyBag = ReflectedPropertyBagProvider.Instance.CreatePropertyBag(type); propertyBag?.Register(); }
static void PostProcessProperty(PropertyInfo property, HashSet <string> includedProperties, HashSet <string> ignoredProperties, HashSet <Type> serializableContainerTypes) { var propertyType = property.PropertyType; if (serializableContainerTypes.Contains(propertyType)) { return; } var propertyName = property.Name; var includeField = includedProperties != null && includedProperties.Contains(propertyName); if (!includeField) { if (ignoredProperties != null && ignoredProperties.Contains(propertyName)) { return; } if (property.GetGetMethod(true) == null) { return; } var setMethod = property.GetSetMethod(true); if (setMethod == null) { return; } var isValidProperty = false; foreach (var attribute in property.CustomAttributes) { var attributeType = attribute.AttributeType; if (attributeType == k_NativePropertyAttributeType) { isValidProperty = true; break; } if (attributeType == k_NativeNameAttributeType) { isValidProperty = true; break; } } // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags if ((setMethod.MethodImplementationFlags & MethodImplAttributes.InternalCall) != 0) { isValidProperty = true; } if (!isValidProperty) { return; } } if (propertyType.IsArray) { propertyType = propertyType.GetElementType(); } else if (ReflectedPropertyBagUtils.IsListType(propertyType)) { propertyType = propertyType.GenericTypeArguments[0]; } if (!CodeGenUtils.IsSerializableContainer(propertyType)) { return; } serializableContainerTypes.Add(propertyType); }
static void PostProcessField(FieldInfo field, HashSet <string> includedProperties, HashSet <string> ignoredProperties, HashSet <Type> serializableContainerTypes) { var fieldType = field.FieldType; if (serializableContainerTypes.Contains(fieldType)) { return; } var fieldName = field.Name; var includeField = includedProperties != null && includedProperties.Contains(fieldName); if (!includeField) { if (ignoredProperties != null && ignoredProperties.Contains(fieldName)) { return; } if (!field.IsPublic) { var isValidField = false; foreach (var attribute in field.GetCustomAttributes()) { var attributeType = attribute.GetType(); if (attributeType == k_NativeNameAttributeType || attributeType == typeof(SerializableAttribute)) { isValidField = true; } if (attributeType == k_IgnoreAttributeType) { isValidField = false; break; } } if (!isValidField) { return; } } } if (fieldType.IsArray) { fieldType = fieldType.GetElementType(); } else if (ReflectedPropertyBagUtils.IsListType(fieldType)) { fieldType = fieldType.GenericTypeArguments[0]; } if (fieldType == null || fieldType.IsGenericParameter || fieldType.IsGenericType) { return; } if (!CodeGenUtils.IsSerializableContainer(fieldType)) { return; } serializableContainerTypes.Add(fieldType); }
static void PostProcessAssembly(HashSet <string> namespaceExceptions, HashSet <string> typeExceptions, Assembly assembly, List <FieldInfo> fields, List <PropertyInfo> properties, HashSet <Type> serializableContainerTypes) { foreach (var type in assembly.ExportedTypes) { if (type.IsAbstract || type.IsInterface) { continue; } if (type.IsGenericType) { continue; } if (!typeof(Component).IsAssignableFrom(type)) { continue; } var typeName = type.FullName; if (string.IsNullOrEmpty(typeName)) { continue; } if (typeExceptions.Contains(typeName)) { continue; } var partOfNamespaceException = false; var typeNamespace = type.Namespace; if (!string.IsNullOrEmpty(typeNamespace)) { foreach (var exception in namespaceExceptions) { if (typeNamespace.Contains(exception)) { partOfNamespaceException = true; break; } } } if (partOfNamespaceException) { continue; } var includedProperties = ReflectedPropertyBagUtils.GetIncludedProperties(typeName); var ignoredProperties = ReflectedPropertyBagUtils.GetIgnoredProperties(typeName); serializableContainerTypes.Add(type); fields.Clear(); type.GetFieldsRecursively(fields, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var field in fields) { PostProcessField(field, includedProperties, ignoredProperties, serializableContainerTypes); } properties.Clear(); type.GetPropertiesRecursively(properties, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var property in properties) { PostProcessProperty(property, includedProperties, ignoredProperties, serializableContainerTypes); } } }