コード例 #1
0
ファイル: PersistentField.cs プロジェクト: gomker/KSPDev
        /// <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;
                }
            }
        }
コード例 #2
0
        /// <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));
            }
        }