/// <summary> /// Function to save the sprites to the file system. /// </summary> /// <param name="path">The path to save the sprites into.</param> /// <param name="baseFileName">The base file name.</param> /// <param name="sprites">The sprites to save.</param> /// <param name="textureFile">The texture file associated with the sprites.</param> /// <exception cref="IOException">Thrown when the file system is locked by another thread (after 10 seconds).</exception> public void SaveSprites(string path, string baseFileName, IEnumerable <GorgonSprite> sprites, IContentFile textureFile) { int spriteIndex = 1; try { string fileName = Path.GetFileNameWithoutExtension(baseFileName); string extension = Path.GetExtension(baseFileName); if ((!string.IsNullOrWhiteSpace(extension)) && (extension[0] != '.')) { extension = "." + extension; } if (!_fileManager.BeginBatch()) { throw new IOException(Resources.GOREST_ERR_CANNOT_ACCESS_FILESYSTEM_LOCK); } foreach (GorgonSprite sprite in sprites) { string filePath = $"{path}{fileName} ({spriteIndex++}){(string.IsNullOrWhiteSpace(extension) ? string.Empty : extension)}"; while (_fileManager.GetFile(filePath) != null) { filePath = $"{path}{fileName} ({spriteIndex++}){(string.IsNullOrWhiteSpace(extension) ? string.Empty : extension)}"; } IContentFile outputFile = _fileManager.WriteFile(filePath, stream => { _defaultCodec.Save(sprite, stream); }); textureFile.LinkContent(outputFile); } } finally { _fileManager.EndBatch(); } }
/// <summary>Function to save the atlas data.</summary> /// <param name="atlas">The atlas data to save.</param> public void SaveAtlas(IReadOnlyDictionary <IContentFile, GorgonSprite> spriteFiles, GorgonTextureAtlas atlas) { IGorgonImage image = null; string directory = Path.GetDirectoryName(atlas.Textures[0].Texture.Name).FormatDirectory('/'); Stream outStream = null; try { _fileSystem.BeginBatch(); if (!_fileSystem.DirectoryExists(directory)) { _fileSystem.CreateDirectory(directory); } void WriteImageFile(Stream stream) => _defaultImageCodec.SaveToStream(image, stream); // Check the files to ensure they're not open for editing. foreach (GorgonTexture2DView texture in atlas.Textures) { IContentFile textureFile = _fileSystem.GetFile(texture.Texture.Name); if ((textureFile != null) && (textureFile.IsOpen)) { throw new IOException(string.Format(Resources.GORTAG_ERR_IMAGE_OPEN, textureFile.Path)); } } foreach ((GorgonSprite original, GorgonSprite sprite) in atlas.Sprites) { IContentFile oldFile = spriteFiles.FirstOrDefault(item => item.Value == original).Key; if ((oldFile != null) && (oldFile.IsOpen)) { throw new IOException(string.Format(Resources.GORTAG_ERR_IMAGE_OPEN, oldFile.Path)); } } // Write textures. foreach (GorgonTexture2DView texture in atlas.Textures) { image = texture.Texture.ToImage(); _fileSystem.WriteFile(texture.Texture.Name, WriteImageFile); image.Dispose(); } // Write out the updated sprites. foreach ((GorgonSprite original, GorgonSprite sprite) in atlas.Sprites) { IContentFile oldTextureFile = null; IContentFile textureFile = _fileSystem.GetFile(sprite.Texture.Texture.Name); IContentFile oldFile = spriteFiles.FirstOrDefault(item => item.Value == original).Key; if (oldFile.Metadata.DependsOn.TryGetValue(CommonEditorContentTypes.ImageType, out string oldTexturePath)) { oldTextureFile = _fileSystem.GetFile(oldTexturePath); } outStream = oldFile.OpenWrite(); _defaultSpriteCodec.Save(sprite, outStream); textureFile.LinkContent(oldFile); oldTextureFile?.UnlinkContent(oldFile); oldFile.RefreshMetadata(); oldFile.Refresh(); outStream.Dispose(); } } finally { outStream?.Dispose(); image?.Dispose(); _fileSystem.EndBatch(); } }