bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func <EventReader, Type, object> nestedObjectDeserializer, out object value) { value = null; var evt = reader.Peek <NodeEvent>(); var isNull = evt != null && NodeIsNull(evt); if (isNull) { reader.Skip(); } return(isNull); }
bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func<EventReader, Type, object> nestedObjectDeserializer, out object value) { value = null; var evt = reader.Peek<NodeEvent>(); var isNull = evt != null && NodeIsNull(evt); if (isNull) { reader.Skip(); } return isNull; }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) return false; assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetSerializer.FindSerializer(assetFileExtension); if (!(serializer is AssetYamlSerializer)) return false; // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = 0; int expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect<StreamStart>(); yamlEventReader.Expect<DocumentStart>(); var mappingStart = yamlEventReader.Expect<MappingStart>(); var yamlSerializerSettings = YamlSerializer.GetSerializerSettings(); var tagTypeRegistry = yamlSerializerSettings.TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); expectedVersion = AssetRegistry.GetCurrentFormatVersion(assetType); Scalar assetKey; while ((assetKey = yamlEventReader.Allow<Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == "Id") { yamlEventReader.Skip(); continue; } if (assetKey.Value == "SerializedVersion") { serializedVersion = Convert.ToInt32(yamlEventReader.Expect<Scalar>().Value, CultureInfo.InvariantCulture); break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Paradox) throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion)); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); // transform the stream into string. string assetAsString; using (var assetStream = loadAsset.OpenStream()) using (var assetStreamReader = new StreamReader(assetStream, Encoding.UTF8)) { assetAsString = assetStreamReader.ReadToEnd(); } // Load the asset as a YamlNode object var input = new StringReader(assetAsString); var yamlStream = new YamlStream(); yamlStream.Load(input); var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType); if (assetUpgraders == null) { throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion)); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { int targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); upgrader.Upgrade(context, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; var newSerializedVersion = 0; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode)) { newSerializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value); } if (newSerializedVersion != expectedVersion) { throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, newSerializedVersion, expectedVersion)); } context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent; // Save asset back to disk using (var memoryStream = new MemoryStream()) { using (var streamWriter = new StreamWriter(memoryStream)) { yamlStream.Save(streamWriter, true, preferredIndent); } loadAsset.AssetContent = memoryStream.ToArray(); } return true; } return false; }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) { return(false); } assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetFileSerializer.FindSerializer(assetFileExtension); if (!(serializer is YamlAssetSerializer)) { return(false); } // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = PackageVersion.Zero; PackageVersion expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect <StreamStart>(); yamlEventReader.Expect <DocumentStart>(); var mappingStart = yamlEventReader.Expect <MappingStart>(); var tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType); expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero; Scalar assetKey; while ((assetKey = yamlEventReader.Allow <Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == nameof(Asset.Id)) { yamlEventReader.Skip(); } else if (assetKey.Value == nameof(Asset.SerializedVersion)) { // Check for old format: only a scalar var scalarVersion = yamlEventReader.Allow <Scalar>(); if (scalarVersion != null) { serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture)); // Let's update to new format using (var yamlAsset = loadAsset.AsYamlAsset()) { yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion); var baseBranch = yamlAsset.DynamicRootNode["~Base"]; if (baseBranch != null) { var baseAsset = baseBranch["Asset"]; if (baseAsset != null) { baseAsset.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion); } } } } else { // New format: package => version mapping yamlEventReader.Expect <MappingStart>(); while (!yamlEventReader.Accept <MappingEnd>()) { var packageName = yamlEventReader.Expect <Scalar>().Value; var packageVersion = PackageVersion.Parse(yamlEventReader.Expect <Scalar>().Value); // For now, we handle only one dependency at a time if (packageName == dependencyName) { serializedVersion = packageVersion; } } yamlEventReader.Expect <MappingEnd>(); } break; } else { // If anything else than Id or SerializedVersion, let's stop break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Stride) throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Stride?"); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} needs update, from version {serializedVersion} to version {expectedVersion}"); using (var yamlAsset = loadAsset.AsYamlAsset()) { var yamlRootNode = yamlAsset.RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName); if (assetUpgraders == null) { throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found"); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { PackageVersion targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); // Stop if the next version would be higher than what is expected if (untilVersion != null && targetVersion > untilVersion) { break; } upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; PackageVersion newSerializedVersion = null; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode)) { var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)]; newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value); } if (untilVersion == null && newSerializedVersion != expectedVersion) { throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}."); } context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} updated from version {serializedVersion} to version {expectedVersion}"); } return(true); } return(false); }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) { return(false); } assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetSerializer.FindSerializer(assetFileExtension); if (!(serializer is AssetYamlSerializer)) { return(false); } // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = 0; int expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect <StreamStart>(); yamlEventReader.Expect <DocumentStart>(); var mappingStart = yamlEventReader.Expect <MappingStart>(); var yamlSerializerSettings = YamlSerializer.GetSerializerSettings(); var tagTypeRegistry = yamlSerializerSettings.TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); expectedVersion = AssetRegistry.GetCurrentFormatVersion(assetType); Scalar assetKey; while ((assetKey = yamlEventReader.Allow <Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == "Id") { yamlEventReader.Skip(); continue; } if (assetKey.Value == "SerializedVersion") { serializedVersion = Convert.ToInt32(yamlEventReader.Expect <Scalar>().Value, CultureInfo.InvariantCulture); break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Paradox) throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion)); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); // transform the stream into string. string assetAsString; using (var assetStream = loadAsset.OpenStream()) using (var assetStreamReader = new StreamReader(assetStream, Encoding.UTF8)) { assetAsString = assetStreamReader.ReadToEnd(); } // Load the asset as a YamlNode object var input = new StringReader(assetAsString); var yamlStream = new YamlStream(); yamlStream.Load(input); var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType); if (assetUpgraders == null) { throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion)); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { int targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); upgrader.Upgrade(context, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; var newSerializedVersion = 0; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode)) { newSerializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value); } if (newSerializedVersion != expectedVersion) { throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, newSerializedVersion, expectedVersion)); } context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent; // Save asset back to disk using (var memoryStream = new MemoryStream()) { using (var streamWriter = new StreamWriter(memoryStream)) { yamlStream.Save(streamWriter, true, preferredIndent); } loadAsset.AssetContent = memoryStream.ToArray(); } return(true); } return(false); }
public static bool MigrateAssetIfNeeded(AssetMigrationContext context, PackageLoadingAssetFile loadAsset, string dependencyName, PackageVersion untilVersion = null) { var assetFullPath = loadAsset.FilePath.FullPath; // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) return false; assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetFileSerializer.FindSerializer(assetFileExtension); if (!(serializer is YamlAssetSerializer)) return false; // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = PackageVersion.Zero; PackageVersion expectedVersion; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var assetStream = loadAsset.OpenStream()) using (var streamReader = new StreamReader(assetStream)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect<StreamStart>(); yamlEventReader.Expect<DocumentStart>(); var mappingStart = yamlEventReader.Expect<MappingStart>(); var tagTypeRegistry = AssetYamlSerializer.Default.GetSerializerSettings().TagTypeRegistry; bool typeAliased; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag, out typeAliased); var expectedVersions = AssetRegistry.GetCurrentFormatVersions(assetType); expectedVersion = expectedVersions?.FirstOrDefault(x => x.Key == dependencyName).Value ?? PackageVersion.Zero; Scalar assetKey; while ((assetKey = yamlEventReader.Allow<Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == nameof(Asset.Id)) { yamlEventReader.Skip(); } else if (assetKey.Value == nameof(Asset.SerializedVersion)) { // Check for old format: only a scalar var scalarVersion = yamlEventReader.Allow<Scalar>(); if (scalarVersion != null) { serializedVersion = PackageVersion.Parse("0.0." + Convert.ToInt32(scalarVersion.Value, CultureInfo.InvariantCulture)); // Let's update to new format using (var yamlAsset = loadAsset.AsYamlAsset()) { yamlAsset.DynamicRootNode.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(yamlAsset.DynamicRootNode, dependencyName, serializedVersion); var baseBranch = yamlAsset.DynamicRootNode["~Base"]; if (baseBranch != null) { var baseAsset = baseBranch["Asset"]; if (baseAsset != null) { baseAsset.RemoveChild(nameof(Asset.SerializedVersion)); AssetUpgraderBase.SetSerializableVersion(baseAsset, dependencyName, serializedVersion); } } } } else { // New format: package => version mapping yamlEventReader.Expect<MappingStart>(); while (!yamlEventReader.Accept<MappingEnd>()) { var packageName = yamlEventReader.Expect<Scalar>().Value; var packageVersion = PackageVersion.Parse(yamlEventReader.Expect<Scalar>().Value); // For now, we handle only one dependency at a time if (packageName == dependencyName) { serializedVersion = packageVersion; } } yamlEventReader.Expect<MappingEnd>(); } break; } else { // If anything else than Id or SerializedVersion, let's stop break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Xenko) throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Xenko?"); } if (serializedVersion < expectedVersion) { // Perform asset upgrade context.Log.Verbose("{0} needs update, from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); using (var yamlAsset = loadAsset.AsYamlAsset()) { var yamlRootNode = yamlAsset.RootNode; // Check if there is any asset updater var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName); if (assetUpgraders == null) { throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found"); } // Instantiate asset updaters var currentVersion = serializedVersion; while (currentVersion != expectedVersion) { PackageVersion targetVersion; // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error. var upgrader = assetUpgraders.GetUpgrader(currentVersion, out targetVersion); // Stop if the next version would be higher than what is expected if (untilVersion != null && targetVersion > untilVersion) break; upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset); currentVersion = targetVersion; } // Make sure asset is updated to latest version YamlNode serializedVersionNode; PackageVersion newSerializedVersion = null; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out serializedVersionNode)) { var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)]; newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value); } if (untilVersion == null && newSerializedVersion != expectedVersion) { throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}."); } context.Log.Info("{0} updated from version {1} to version {2}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); } return true; } return false; }
public static bool MigrateAssetIfNeeded(ILogger log, string assetFullPath) { // Determine if asset was Yaml or not var assetFileExtension = Path.GetExtension(assetFullPath); if (assetFileExtension == null) { return(false); } assetFileExtension = assetFileExtension.ToLowerInvariant(); var serializer = AssetSerializer.FindSerializer(assetFileExtension); if (!(serializer is AssetYamlSerializer)) { return(false); } // We've got a Yaml asset, let's get expected and serialized versions var serializedVersion = 0; var expectedVersion = 0; Type assetType; // Read from Yaml file the asset version and its type (to get expected version) // Note: It tries to read as few as possible (SerializedVersion is expected to be right after Id, so it shouldn't try to read further than that) using (var streamReader = new StreamReader(assetFullPath)) { var yamlEventReader = new EventReader(new Parser(streamReader)); // Skip header yamlEventReader.Expect <StreamStart>(); yamlEventReader.Expect <DocumentStart>(); var mappingStart = yamlEventReader.Expect <MappingStart>(); var yamlSerializerSettings = YamlSerializer.GetSerializerSettings(); var tagTypeRegistry = yamlSerializerSettings.TagTypeRegistry; assetType = tagTypeRegistry.TypeFromTag(mappingStart.Tag); expectedVersion = AssetRegistry.GetFormatVersion(assetType); Scalar assetKey; while ((assetKey = yamlEventReader.Allow <Scalar>()) != null) { // Only allow Id before SerializedVersion if (assetKey.Value == "Id") { yamlEventReader.Skip(); continue; } if (assetKey.Value == "SerializedVersion") { serializedVersion = Convert.ToInt32(yamlEventReader.Expect <Scalar>().Value, CultureInfo.InvariantCulture); break; } } } if (serializedVersion > expectedVersion) { // Try to open an asset newer than what we support (probably generated by a newer Paradox) throw new InvalidOperationException(string.Format("Asset of type {0} has been serialized with newer version {1}, but only version {2} is supported. Was this asset created with a newer version of Paradox?", assetType, serializedVersion, expectedVersion)); } if (serializedVersion < expectedVersion) { // Perform asset upgrade log.Info("{0} needs update, from version {0} to version {1}", Path.GetFullPath(assetFullPath), serializedVersion, expectedVersion); // Load the asset as a YamlNode object var input = new StringReader(File.ReadAllText(assetFullPath)); var yamlStream = new YamlStream(); yamlStream.Load(input); var yamlRootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; // Check if there is any asset updater var assetUpdaterTypes = AssetRegistry.GetFormatVersionUpdaterTypes(assetType); if (assetUpdaterTypes == null) { throw new InvalidOperationException(string.Format("Asset of type {0} should be updated from version {1} to {2}, but no asset migration path was found", assetType, serializedVersion, expectedVersion)); } // Instantiate asset updaters var assetUpgraders = assetUpdaterTypes.Select(x => (IAssetUpgrader)Activator.CreateInstance(x)).ToArray(); // TODO: Select best asset updater if more than one (need to check from what to what version they update, score, if multiple need to be chained, etc...) // I think it's better to wait for some actual scenarios to implement this right the first time if (assetUpgraders.Length != 1) { throw new InvalidOperationException(string.Format("Asset of type {0} has multiple migration paths, but selecting the right one is not implemented yet.", assetType)); } // Perform upgrade assetUpgraders[0].Upgrade(log, yamlRootNode); // Make sure asset is updated to latest version YamlNode serializedVersionNode; serializedVersion = 0; if (yamlRootNode.Children.TryGetValue(new YamlScalarNode("SerializedVersion"), out serializedVersionNode)) { serializedVersion = Convert.ToInt32(((YamlScalarNode)serializedVersionNode).Value); } if (serializedVersion != expectedVersion) { throw new InvalidOperationException(string.Format("Asset of type {0} was migrated, but still its new version {1} doesn't match expected version {2}.", assetType, serializedVersion, expectedVersion)); } var preferredIndent = YamlSerializer.GetSerializerSettings().PreferredIndent; // Save asset back to disk using (var streamWriter = new StreamWriter(assetFullPath)) yamlStream.Save(streamWriter, true, preferredIndent); return(true); } return(false); }