/// <summary>Restores a collection from the config node.</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 ReadCollectionFromConfig(ConfigNode node, object instance) { var value = fieldInfo.GetValue(instance); if (value == null) { // Collections are the complex objects, they must exist in order to be restored. DebugEx.Warning("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) { DebugEx.Error("Cannot parse value \"{0}\" as {1}: {2}", itemCfgs, collectionProto.GetItemType().FullName, ex.Message); } } } } }
/// <summary>Creates a collection from the config node.</summary> /// <param name="node">A node to read data from.</param> /// <returns>Сollection instance.</returns> internal object DeserializeValues(ConfigNode node) { object instance = null; var values = persistentField.ordinaryFieldHandler.IsCompound() ? ConfigAccessor.GetNodesByPath(node, persistentField.cfgPath) as object[] : ConfigAccessor.GetValuesByPath(node, persistentField.cfgPath) as object[]; if (values != null) { instance = Activator.CreateInstance(collectionType); foreach (var value in values) { var item = persistentField.ordinaryFieldHandler.DeserializeValue(value); if (item != null) { collectionProto.AddItem(instance, item); } } } return(instance); }
/// <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); } } } } }