/// <param name="fieldInfo">An annotated field metadata.</param> /// <param name="fieldAttr">An annotation of the field.</param> public PersistentField(FieldInfo fieldInfo, PersistentFieldAttribute fieldAttr) { this.fieldInfo = fieldInfo; cfgPath = fieldAttr.path; var ordinaryType = fieldInfo.FieldType; if (fieldAttr.collectionTypeProto != null) { collectionProto = Activator.CreateInstance(fieldAttr.collectionTypeProto, new[] { fieldInfo.FieldType }) as AbstractCollectionTypeProto; ordinaryType = collectionProto.GetItemType(); } simpleTypeProto = Activator.CreateInstance(fieldAttr.ordinaryTypeProto) as AbstractOrdinaryValueTypeProto; isCustomSimpleType = typeof(IPersistentField).IsAssignableFrom(ordinaryType); // Determine if field's or collection item's type is a class (compound type). isCompound = !simpleTypeProto.CanHandle(ordinaryType) && !isCustomSimpleType && (ordinaryType.IsValueType && !ordinaryType.IsEnum || // IsStruct ordinaryType.IsClass && ordinaryType != typeof(string) && !ordinaryType.IsEnum); // IsClass if (!isCompound && !simpleTypeProto.CanHandle(ordinaryType) && !isCustomSimpleType) { Debug.LogErrorFormat( "Proto {0} cannot handle value in field {1}.{2}", ordinaryType.FullName, fieldInfo.DeclaringType.FullName, fieldInfo.Name); isDisabled = true; } // For a compound type retrieve all its persisted fields. if (isCompound && !isDisabled) { // Ignore static fields of the compound type since it can be used by multiple persistent // fields or as an item in a collection field. // Also, ignore groups in the compound types to reduce configuration complexity. compoundTypeFields = PersistentFieldsFactory.GetPersistentFields( ordinaryType, false /* needStatic */, true /* needInstance */, null /* group */) // Parent nodes have to be handled before children! .OrderBy(x => string.Join("/", x.cfgPath)) .ToArray(); // Disable if cannot deal with the field anyways. if (compoundTypeFields.Length == 0 && !typeof(IConfigNode).IsAssignableFrom(ordinaryType)) { Debug.LogErrorFormat( "Compound type in field {0}.{1} has no persistent fields and doesn't implement" + " IConfigNode", fieldInfo.DeclaringType.FullName, fieldInfo.Name); isDisabled = true; } } }
/// <param name="persistentField">A descriptor of persistent field which holds the value.</param> /// <param name="collectionType">A type of the collection this handler will be handling.</param> /// <param name="collectionProtoType">A proto type that can work with the collection.</param> internal CollectionFieldHandler( PersistentField persistentField, Type collectionType, Type collectionProtoType) { this.collectionType = collectionType; this.persistentField = persistentField; this.collectionProto = Activator.CreateInstance(collectionProtoType, new[] { collectionType }) as AbstractCollectionTypeProto; if (this.collectionProto == null) { throw new ArgumentException(string.Format("Bad collection proto {0}", collectionProtoType)); } }