/// <summary> /// Restores an ordinary value collection from the config node. The type can be compound. /// </summary> /// <remarks>This method never throws.</remarks> /// <param name="node">The node to read the state from.</param> /// <param name="instance"> /// The owner of the field. It can be <c>null</c> for the static fields. /// </param> void ReadOrdinaryFromConfig(ConfigNode node, object instance) { var value = fieldInfo.GetValue(instance); if (isCompound) { var cfgNode = ConfigAccessor.GetNodeByPath(node, cfgPath); if (cfgNode != null) { if (value == null) { // Try creating the instance using its default constructor. if (fieldInfo.IsInitOnly) { DebugEx.Warning( "Cannot assign to a NULL readonly compound field! Field is ignored: {0}.{1}", fieldInfo.DeclaringType.FullName, fieldInfo.Name); return; } try { value = Activator.CreateInstance(fieldInfo.FieldType); fieldInfo.SetValue(instance, value); } catch (Exception ex) { DebugEx.Error("Cannot restore field of type {0}: {1}", fieldInfo.FieldType, ex.Message); } } DeserializeCompoundFieldsFromNode(cfgNode, value); } } else { if (fieldInfo.IsInitOnly) { DebugEx.Warning("Cannot assign to a readonly field! Field is ignored: {0}.{1}", fieldInfo.DeclaringType.FullName, fieldInfo.Name); return; } var cfgValue = ConfigAccessor.GetValueByPath(node, cfgPath); if (cfgValue != null) { try { object fieldValue; if (isCustomSimpleType) { // Prefer the existing instance of the field value when available. fieldValue = value ?? Activator.CreateInstance(fieldInfo.FieldType); ((IPersistentField)fieldValue).ParseFromString(cfgValue); } else { fieldValue = simpleTypeProto.ParseFromString(cfgValue, fieldInfo.FieldType); } fieldInfo.SetValue(instance, fieldValue); } catch (Exception ex) { DebugEx.Error("Cannot parse value \"{0}\" as {1}: {2}", cfgValue, fieldInfo.FieldType.FullName, ex.Message); } } } }
/// <summary>Reads field from a config node.</summary> /// <param name="node">A node to read state from.</param> /// <param name="instance">An owner of the field. Can be <c>null</c> for static fields.</param> public void ReadFromConfig(ConfigNode node, object instance) { object value = null; if (collectionFieldHandler != null) { value = collectionFieldHandler.DeserializeValues(node); } else { var cfgData = ordinaryFieldHandler.IsCompound() ? ConfigAccessor.GetNodeByPath(node, cfgPath) as object : ConfigAccessor.GetValueByPath(node, cfgPath) as object; if (cfgData != null) { value = ordinaryFieldHandler.DeserializeValue(cfgData); } } if (value != null) { fieldInfo.SetValue(instance, value); } }
/// <summary>Reads field from a config node.</summary> /// <param name="node">A node to read state from.</param> /// <param name="instance">An owner of the field. Can be <c>null</c> for static fields.</param> public void ReadFromConfig(ConfigNode node, object instance) { var value = fieldInfo.GetValue(instance); if (collectionProto != null) { // For collection field use existing object and restore its items. if (value == null) { Debug.LogWarningFormat("Skip reading collection field {0}.{1} due to it's not initalized", fieldInfo.DeclaringType.FullName, fieldInfo.Name); return; } collectionProto.ClearItems(value); if (isCompound) { // For compound items read nodes and have them parsed. var itemCfgs = ConfigAccessor.GetNodesByPath(node, cfgPath); if (itemCfgs != null) { foreach (var itemCfg in itemCfgs) { var itemValue = Activator.CreateInstance(collectionProto.GetItemType()); DeserializeCompoundFieldsFromNode(itemCfg, itemValue); collectionProto.AddItem(value, itemValue); } } } else { // For ordinary items read strings and have them parsed. var itemCfgs = ConfigAccessor.GetValuesByPath(node, cfgPath); if (itemCfgs != null) { foreach (var itemCfg in itemCfgs) { try { object itemValue; if (isCustomSimpleType) { itemValue = Activator.CreateInstance(collectionProto.GetItemType()); ((IPersistentField)itemValue).ParseFromString(itemCfg); } else { itemValue = simpleTypeProto.ParseFromString(itemCfg, collectionProto.GetItemType()); } collectionProto.AddItem(value, itemValue); } catch (Exception ex) { Debug.LogErrorFormat("Cannot parse value \"{0}\" as {1}: {2}", itemCfgs, collectionProto.GetItemType().FullName, ex.Message); } } } } } else { // For ordinary field just restore value and assign it to the field. if (isCompound) { if (value != null) { DeserializeCompoundFieldsFromNode(ConfigAccessor.GetNodeByPath(node, cfgPath), value); } else { Debug.LogWarningFormat("Skip reading compound field {0}.{1} due to it's not initalized", fieldInfo.DeclaringType.FullName, fieldInfo.Name); } } else { var cfgValue = ConfigAccessor.GetValueByPath(node, cfgPath); if (cfgValue != null) { try { object fieldValue; if (isCustomSimpleType) { // Prefer the existing instance of the field value when available. fieldValue = value ?? Activator.CreateInstance(fieldInfo.FieldType); ((IPersistentField)fieldValue).ParseFromString(cfgValue); } else { fieldValue = simpleTypeProto.ParseFromString(cfgValue, fieldInfo.FieldType); } fieldInfo.SetValue(instance, fieldValue); } catch (Exception ex) { Debug.LogErrorFormat("Cannot parse value \"{0}\" as {1}: {2}", cfgValue, fieldInfo.FieldType.FullName, ex.Message); } } } } }