private void ImportYaml(ImportFile file) { if (file.Imported) { return; } var deserializer = new YamlDotNet.Serialization.Deserializer(); using (var reader = new StreamReader(file.Filename)) { var yaml = deserializer.Deserialize(reader) as Dictionary <object, object>; if (yaml.Keys.Count != 1) { throw new ImportException($"{file.Filename}: invalid yaml format"); } var typeName = yaml.Keys.First() as string; if (typeName == null) { throw new ImportException($"{file.Filename}: invalid yaml format"); } if (!_importersByType.TryGetValue(typeName, out var importer)) { throw new ImportException($"{file.Filename}: not importer defined for type {typeName}"); } file.Importer = importer; } }
private void Import(ImportFile file) { if (file.Imported) { return; } if (file.Importer == null) { if (Path.GetExtension(file.Filename).ToLower() == ".yaml") { ImportYaml(file); } if (file.Importer == null) { throw new ImportException($"{file.Filename}: no importers available"); } } try { // Make sure target directory exists Directory.CreateDirectory(Path.GetDirectoryName(file.TargetFilename)); file.Importer.Import(file); } catch (Exception e) { File.Delete(file.TargetFilename); throw e; } }
public override void Import(ImportFile file) { var doc = new XmlDocument(); doc.Load(file.Filename); using (var writer = new ResourceWriter(File.Create(file.TargetFilename), typeof(TileMap))) Import(file, doc, writer); }
public override void Import(ImportFile file) { MetaDefinition meta = null; var yamlPath = Path.ChangeExtension(file.Filename, ".yaml"); if (File.Exists(yamlPath)) { using (var yamlStream = File.OpenRead(yamlPath)) using (var yamlReader = new StreamReader(yamlStream)) { meta = (new YamlDotNet.Serialization.Deserializer()).Deserialize <MetaDefinition>(yamlReader); } } var border = Thickness.Empty; if (meta != null && meta.Image != null) { border = Thickness.Parse(meta.Image.Border); } if (meta != null && meta.ImageAtlas != null) { var targetPath = Path.ChangeExtension(file.TargetFilename, null); // Create a directory with the same name as the resource Directory.CreateDirectory(targetPath); for (var i = 0; i < meta.ImageAtlas.Images.Length; i++) { using (var sourceFile = File.OpenRead(file.Filename)) using (var targetWriter = new ResourceWriter(File.OpenWrite($"{targetPath}/{meta.ImageAtlas.Images[i].Name}.resource"), typeof(Image))) Import(sourceFile, targetWriter, border, new SixLabors.Primitives.Rectangle( meta.ImageAtlas.Images[i].Rect.x, meta.ImageAtlas.Images[i].Rect.y, meta.ImageAtlas.Images[i].Rect.w, meta.ImageAtlas.Images[i].Rect.h)); // TODO: write the atlas out as a resource } } else { using (var sourceFile = File.OpenRead(file.Filename)) using (var targetWriter = new ResourceWriter(File.OpenWrite(file.TargetFilename), typeof(NoZ.Image))) Import(sourceFile, targetWriter, border, SixLabors.Primitives.Rectangle.Empty); } }
public override void Import(ImportFile file) { var doc = new XmlDocument(); try { doc.Load(file.Filename); } catch { throw new ImportException("failed to parse XML"); } using (var writer = new ResourceWriter(File.Create(file.TargetFilename), typeof(TileSet))) Import(file, doc, writer); }
public override void Import(ImportFile file) { try { using (var reader = new BinaryReader(File.OpenRead(file.Filename))) using (var writer = new ResourceWriter(File.OpenWrite(file.TargetFilename), typeof(AudioClip))) { Import(reader, writer); } } catch (ImportException) { throw; } catch { throw new ImportException("failed to open file for read"); } }
private void Import(ImportFile file, XmlDocument doc, ResourceWriter writer) { var map = doc.GetElementsByTagName("map")[0]; var width = int.Parse(map.Attributes["width"].Value); var height = int.Parse(map.Attributes["height"].Value); writer.Write((ushort)width); writer.Write((ushort)height); writer.Write((ushort)int.Parse(map.Attributes["tilewidth"].Value)); writer.Write((ushort)int.Parse(map.Attributes["tileheight"].Value)); var layers = map.SelectNodes("objectgroup | layer"); var tilesets = map.SelectNodes("tileset"); // Write tile sets var tileSetFirstId = new int[tilesets.Count]; writer.Write((ushort)tileSetFirstId.Length); for (int i = 0; i < tileSetFirstId.Length; i++) { XmlNode tileSet = tilesets[i]; var source = tileSet.Attributes["source"].Value; tileSetFirstId[i] = int.Parse(tileSet.Attributes["firstgid"].Value); var uri1 = new Uri(Path.Combine(Path.GetDirectoryName(file.TargetFilename), source)); var uri2 = new Uri(file.TargetDirectory + "\\"); var name = Path.ChangeExtension(uri2.MakeRelativeUri(uri1).ToString(), null); writer.Write(name); } // Write layers writer.Write((ushort)layers.Count); foreach (XmlNode layer in layers) { writer.Write(layer.Attributes["name"]?.Value ?? ""); writer.Write((ushort)width); writer.Write((ushort)height); // Properties var objprops = layer.SelectNodes("properties/property"); writer.Write((ushort)objprops.Count); foreach (XmlNode objprop in objprops) { writer.Write(objprop.Attributes["name"].Value); writer.Write(objprop.Attributes["value"].Value); } switch (layer.Name) { case "layer": { // Write tiles var data = layer["data"]; var encoding = data.Attributes["encoding"].Value; if (encoding != "csv") { throw new ImportException($"encoding '{encoding}' not supported"); } var ids = data.InnerText.Split(','); writer.Write((ushort)ids.Length); for (int i = 0; i < ids.Length; i++) { var id = int.Parse(ids[i]); if (id == 0) { writer.Write((ushort)0xFFFF); continue; } int tileSetId; for (tileSetId = 0; tileSetId < tileSetFirstId.Length - 1 && id >= tileSetFirstId[tileSetId + 1]; tileSetId++) { ; } writer.Write((ushort)tileSetId); writer.Write((ushort)(id - tileSetFirstId[tileSetId])); } // Write objects writer.Write((ushort)0); break; } case "objectgroup": { // No tiles writer.Write((ushort)0); var properties = layer.SelectNodes("properties/property"); // Write objects var objects = layer.SelectNodes("object"); writer.Write((ushort)objects.Count); foreach (XmlNode o in objects) { XmlNode obj = o; var template = obj.Attributes["template"]?.Value; if (template != null) { var templateDoc = new XmlDocument(); templateDoc.Load(Path.Combine(Path.GetDirectoryName(file.Filename), template)); obj = templateDoc.SelectSingleNode("/template/object"); } writer.Write(o.Attributes["name"]?.Value ?? obj.Attributes["name"]?.Value ?? ""); writer.Write(o.Attributes["type"]?.Value ?? obj.Attributes["type"]?.Value ?? ""); writer.Write(new Vector2(float.Parse(o.Attributes["x"].Value), float.Parse(o.Attributes["y"].Value))); // Point if (obj.SelectSingleNode("point") != null) { writer.Write((byte)TileMap.ShapeType.Point); } // Polygon else if (obj.SelectSingleNode("polygon") != null) { writer.Write((byte)TileMap.ShapeType.Polygon); var points = obj.SelectSingleNode("polygon").Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i])); } } // Polyline else if (obj.SelectSingleNode("polyline") != null) { writer.Write((byte)TileMap.ShapeType.PolyLine); var points = obj.SelectSingleNode("polyline").Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i])); } } // Ellipse else if (obj.SelectSingleNode("ellipse") != null) { writer.Write((byte)TileMap.ShapeType.Circle); writer.Write(float.Parse(o.Attributes["width"]?.Value ?? obj.Attributes["width"]?.Value ?? "0")); writer.Write(float.Parse(o.Attributes["height"]?.Value ?? obj.Attributes["height"]?.Value ?? "0")); } // Box else { writer.Write((byte)TileMap.ShapeType.Box); writer.Write(float.Parse(o.Attributes["width"]?.Value ?? obj.Attributes["width"]?.Value ?? "0")); writer.Write(float.Parse(o.Attributes["height"]?.Value ?? obj.Attributes["height"]?.Value ?? "0")); } // Properties var layerprops = obj.SelectNodes("properties/property"); writer.Write((ushort)layerprops.Count); foreach (XmlNode layerProp in layerprops) { writer.Write(layerProp.Attributes["name"].Value); writer.Write(layerProp.Attributes["value"].Value); } } break; } } } }
/// <summary> /// Import the sprite animation /// </summary> public override void Import(ImportFile file) { using (var sourceFile = File.OpenRead(file.Filename)) using (var targetWriter = new ResourceWriter(File.OpenWrite(file.TargetFilename), typeof(ImageAnimation))) Import(sourceFile, targetWriter); }
/// <summary> /// Import the file with the given name and output it to the given stream /// </summary> public abstract void Import(ImportFile file);
/// <summary> /// Import all files from the source directory to the target directory /// </summary> public void Import(string from, string to) { Initialize(); if (string.IsNullOrEmpty(from)) { throw new ArgumentNullException("from"); } if (string.IsNullOrEmpty(to)) { throw new ArgumentNullException("to"); } if (!Directory.Exists(from)) { throw new DirectoryNotFoundException(from); } // Create the target directory Directory.CreateDirectory(to); var files = Directory.GetFiles(from, "*.*", SearchOption.AllDirectories); foreach (var sourcePath in files) { // Get the relative filename var relativeName = (new Uri(from + "\\")).MakeRelativeUri(new Uri(sourcePath)).ToString(); // TODO: look up extension and associate impoprter // TODO: if extension is yaml then parse yaml and get first entry to determine type var name = Path.ChangeExtension(relativeName, null); var targetName = Path.Combine(to, name); var targetPath = targetName + ".resource"; var targetExt = Path.GetExtension(relativeName); _importersByExtension.TryGetValue(targetExt, out var importer); if (!_files.TryGetValue(name, out var file)) { file = new ImportFile { Filename = sourcePath, Imported = true, Importer = importer }; file.Filename = sourcePath; file.TargetFilename = targetPath; file.Name = name; file.TargetDirectory = to; _files[name] = file; } else if (file.Importer != null && IsSecondaryExtension(file.Importer, targetExt)) { // Ignore the new importer since the currenct one is already handling it as a secondary } else if (importer != null && IsSecondaryExtension(importer, Path.GetExtension(file.Filename))) { file.Importer = importer; file.Filename = sourcePath; } else if (importer != null) { throw new ImportException($"multiple importers defined for resource {name}"); } if (File.Exists(targetPath)) { file.Imported &= (File.GetLastWriteTime(targetPath) >= (DateTimeOffset)File.GetLastWriteTime(sourcePath)); } else if (Directory.Exists(targetName)) { file.Imported &= (Directory.GetLastWriteTime(targetName) >= (DateTimeOffset)File.GetLastWriteTime(sourcePath)); } else { file.Imported = false; } } // Import all files foreach (var file in _files.Values) { Import(file); } }
private void Import(ImportFile file, XmlDocument doc, ResourceWriter writer) { var tileset = doc.GetElementsByTagName("tileset")[0]; var images = doc.GetElementsByTagName("image"); var tiles = doc.GetElementsByTagName("tile"); var columns = int.Parse(tileset.Attributes["columns"].Value); var spacing = int.Parse(tileset.Attributes["spacing"]?.Value ?? "0"); var tilewidth = int.Parse(tileset.Attributes["tilewidth"].Value); var tileheight = int.Parse(tileset.Attributes["tileheight"].Value); var tilecount = int.Parse(tileset.Attributes["tilecount"].Value); if (images.Count == 0) { throw new ImportException("TileSet has no images"); } if (images.Count > 1) { throw new ImportException("Multiple TileSet images not supported"); } var image = images[0].Attributes["source"].Value; if (Path.ChangeExtension(image, null) != Path.GetFileName(file.Name)) { throw new ImportException("TileSet image must be same name as the tile set"); } image = Path.ChangeExtension(file.Filename, Path.GetExtension(image)); writer.Write((ushort)tilewidth); writer.Write((ushort)tileheight); writer.Write((ushort)tilecount); writer.Write((ushort)tiles.Count); // Write the image using (var source = File.OpenRead(image)) ImageImporter.Import(source, writer, Thickness.Empty, SixLabors.Primitives.Rectangle.Empty); // Embed the tile images into the tile set foreach (XmlNode tile in tiles) { var id = int.Parse(tile.Attributes["id"].Value); var x = id % columns; var y = id / columns; x = (x * tilewidth) + x * spacing; y = (y * tileheight) + y * spacing; writer.Write((ushort)id); writer.Write((ushort)x); writer.Write((ushort)y); WriteProperties(writer, tile["properties"]); var objectGroup = tile["objectgroup"]; if (objectGroup != null) { writer.Write((ushort)objectGroup.ChildNodes.Count); foreach (XmlNode obj in objectGroup) { var objx = int.Parse(obj.Attributes["x"].Value); var objy = int.Parse(obj.Attributes["y"].Value); var polygon = obj["polygon"]; if (null != polygon) { var points = polygon.Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i]) + new Vector2(objx, objy)); } } else { writer.Write((ushort)0); } WriteProperties(writer, obj["properties"]); } } else { writer.Write((ushort)0); } } }