#region Using Statements using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Text; using System.Xml; using ANX.Framework.Graphics; using ANX.Framework.NonXNA.Development; #endregion // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license namespace ANX.Framework.Content.Pipeline.Tasks { //comment by author: if you find any mistakes in my language, go fix them ;-) [Developer("SilentWarrior/Eagle Eye Studios")] [PercentageComplete(100)] [TestState(TestStateAttribute.TestState.InProgress)] public class ContentProject { #region Properties /// /// Name of the Content Project /// public String Name { get; set; } /// /// Major version of the project format /// [Browsable(false)] public int VersionMajor { get { return 1; } } /// /// Minor version of the project format. /// Used to keep backwards compatibility /// [Browsable(false)] public int VersionMinor { get { return 2; } } //before you commit your changes, please increase this value by one (and if you added stuff, please check the version before you read anything out of a file). /// /// The directory where the compiled output will be placed /// public String OutputDirectory { get; set; } /// /// The Source root directory where the majority of files is located in. /// public String InputDirectory { get; set; } /// /// The Content Root Directory. Default value is "Content". /// public String ContentRoot { get; set; } /// /// A list containing all build items of this project /// public List BuildItems { get; private set; } /// /// A custom directory to look for custom importers/processors /// public String ReferenceIncludeDirectory { get; set; } /// /// List which holds Assemblies that contain custom importers/processors /// public List References { get; set; } /// /// Name of the tool that generated the resulting file. Might be useful for tracking down /// bugs in that particular application. /// public String Creator { get; set; } /// /// Target Graphics Profile /// public GraphicsProfile Profile { get; set; } /// /// The configuration. Can be "Debug" or "Release". /// [TypeConverter(typeof(BuildModeConverter))] public String Configuration { get; set; } /// /// The platform the content will be compiled for. /// public TargetPlatform Platform { get; set; } #endregion /// /// Initializes a new instance of a /// /// Name of the project public ContentProject(String name) { Name = name; OutputDirectory = "bin"; BuildItems = new List(); References = new List(); } #region Save /// /// Saves the project into a file. Should be a .cproj extension. /// /// The path to save the project public void Save(string path) { //TODO: check file extension and throw exception when wrong (or silently change it?) if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); XmlWriter writer = XmlTextWriter.Create(path, new XmlWriterSettings() {Encoding = Encoding.UTF8, Indent = true, NewLineHandling = NewLineHandling.Entitize} ); writer.WriteStartDocument(); // writer.WriteStartElement("ContentProject"); writer.WriteStartAttribute("Version"); writer.WriteValue(VersionMajor + "." + VersionMinor); writer.WriteEndAttribute(); writer.WriteStartAttribute("Creator"); writer.WriteValue(Creator); writer.WriteEndAttribute(); //Name writer.WriteStartElement("ProjectName"); writer.WriteValue(Name); writer.WriteEndElement(); //Debug writer.WriteStartElement("Configuration"); writer.WriteValue(Configuration); writer.WriteEndElement(); //Reach writer.WriteStartElement("Profile"); writer.WriteValue(Profile.ToString()); writer.WriteEndElement(); //Windows writer.WriteStartElement("Platform"); writer.WriteValue(Platform.ToString()); writer.WriteEndElement(); //A:\Somewhere writer.WriteStartElement("OutputPath"); writer.WriteValue(OutputDirectory); writer.WriteEndElement(); //A:\Somewhere writer.WriteStartElement("InputPath"); writer.WriteValue(InputDirectory); writer.WriteEndElement(); //Content writer.WriteStartElement("ContentRoot"); writer.WriteValue(ContentRoot); writer.WriteEndElement(); // // ANX.Framework.Content.Pipeline.SomewhatImporter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=blah, ProcessorArch=MSIL // writer.WriteStartElement("References"); writer.WriteStartAttribute("IncludeDir"); writer.WriteString(ReferenceIncludeDirectory); writer.WriteEndAttribute(); foreach (var reference in References) { writer.WriteStartElement("Reference"); writer.WriteValue(reference); writer.WriteEndElement(); } writer.WriteEndElement(); // // // A:\MyPicture.png // // True // // // writer.WriteStartElement("BuildItems"); foreach (var buildItem in BuildItems) { writer.WriteStartElement("BuildItem"); writer.WriteStartAttribute("AssetName"); writer.WriteValue(buildItem.AssetName); writer.WriteEndAttribute(); writer.WriteStartAttribute("OutputFilename"); writer.WriteValue(buildItem.OutputFilename); writer.WriteEndAttribute(); writer.WriteStartAttribute("Importer"); writer.WriteValue(buildItem.ImporterName); writer.WriteEndAttribute(); writer.WriteStartAttribute("Processor"); writer.WriteValue(buildItem.ProcessorName); writer.WriteEndAttribute(); writer.WriteStartElement("SourceFile"); writer.WriteValue(buildItem.SourceFilename); writer.WriteEndElement(); writer.WriteStartElement("ProcessorParams"); foreach (var pair in buildItem.ProcessorParameters) { writer.WriteStartElement("Parameter"); writer.WriteStartAttribute("Name"); writer.WriteValue(pair.Key); writer.WriteEndAttribute(); writer.WriteValue(pair.Value); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Flush(); writer.Close(); } #endregion #region Load private static BuildItem lastBuildItem = null; public static ContentProject Load(string path) { if (!File.Exists(path)) throw new FileNotFoundException("The content project you tried to load does not exist: ", path); var reader = XmlTextReader.Create(path); ContentProject project = null; String creator = null; int versionMajor = 0; int versionMinor = 0; while (!reader.EOF) { var readerName = reader.Name; switch (readerName) { case "ProjectName": project = new ContentProject(reader.ReadElementContentAsString()); break; case "ContentProject": reader.MoveToAttribute("Version"); if (reader.NodeType == XmlNodeType.Attribute) { versionMajor = Convert.ToInt32(reader.ReadContentAsString().Split('.')[0]); versionMinor = Convert.ToInt32(reader.ReadContentAsString().Split('.')[1]); } break; case "Creator": if (reader.NodeType == XmlNodeType.Attribute) creator = reader.ReadContentAsString(); break; case "Configuration": if (reader.NodeType == XmlNodeType.Element) if (versionMajor == 1 && versionMinor >= 0) project.Configuration = reader.ReadElementContentAsString(); break; case "Profile": if (reader.NodeType == XmlNodeType.Element) { if (versionMinor < 2) project.Profile = GraphicsProfile.Reach; else { string profileElement = reader.ReadElementContentAsString(); GraphicsProfile profile; if (Enum.TryParse(profileElement, true, out profile)) { project.Profile = profile; } } } break; case "Platform": if (reader.NodeType == XmlNodeType.Element) { if (versionMajor == 1 && versionMinor >= 0) { string platformElement = reader.ReadElementContentAsString(); TargetPlatform targetPlatform; if (Enum.TryParse(platformElement, true, out targetPlatform)) { project.Platform = targetPlatform; } } } break; case "OutputPath": if (reader.NodeType == XmlNodeType.Element) if (versionMajor == 1 && versionMinor >= 0) project.OutputDirectory = reader.ReadElementContentAsString(); break; case "InputPath": if (reader.NodeType == XmlNodeType.Element) if (versionMajor == 1 && versionMinor >= 0) project.InputDirectory = reader.ReadElementContentAsString(); break; case "ContentRoot": if (reader.NodeType == XmlNodeType.Element) if (versionMajor == 1 && versionMinor >= 0) project.ContentRoot = reader.ReadElementContentAsString(); break; case "IncludeDir": if (reader.NodeType == XmlNodeType.Attribute) project.ReferenceIncludeDirectory = reader.ReadContentAsString(); break; case "Reference": if (reader.NodeType == XmlNodeType.Element) if (versionMajor == 1 && versionMinor >= 0) project.References.Add(reader.ReadElementContentAsString()); break; case "BuildItem": if (versionMajor == 1 && versionMinor >= 0) { if (reader.NodeType != XmlNodeType.Element) break; var buildItem = new BuildItem(); lastBuildItem = buildItem; reader.MoveToFirstAttribute(); while (reader.NodeType == XmlNodeType.Attribute) { switch (reader.Name) { case "AssetName": buildItem.AssetName = reader.ReadContentAsString(); reader.MoveToNextAttribute(); break; case "OutputFilename": buildItem.OutputFilename = reader.ReadContentAsString(); reader.MoveToNextAttribute(); break; case "Importer": buildItem.ImporterName = reader.ReadContentAsString(); reader.MoveToNextAttribute(); break; case "Processor": buildItem.ProcessorName = reader.ReadContentAsString(); if (buildItem.AssetName == null) reader.MoveToNextAttribute(); else reader.Read(); break; case "": reader.Read(); break; } } project.BuildItems.Add(buildItem); } break; case "SourceFile": if (versionMajor == 1 && versionMinor >= 0) { if (reader.NodeType == XmlNodeType.Element) lastBuildItem.SourceFilename = reader.ReadElementContentAsString(); } break; case "Parameter": if (versionMajor == 1 && versionMinor >= 0) { string key; object value; reader.MoveToNextAttribute(); key = reader.ReadContentAsString(); reader.MoveToContent(); value = reader.ReadElementContentAsObject(); lastBuildItem.ProcessorParameters.Add(key, value); } break; } reader.Read(); } reader.Close(); //Check for features that were added in format version 1.1 if (project.InputDirectory == null) project.InputDirectory = ""; if (project.ReferenceIncludeDirectory == null) project.ReferenceIncludeDirectory = ""; return project; } #endregion } }