diff --git a/Tools/ProjectConverter/NamespaceMapper.cs b/Tools/ProjectConverter/NamespaceMapper.cs new file mode 100644 index 00000000..384924f3 --- /dev/null +++ b/Tools/ProjectConverter/NamespaceMapper.cs @@ -0,0 +1,156 @@ +#region Using Statements +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +#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 ProjectConverter +{ + internal class NamespaceMapping + { + public string Xna { get; set; } + public string Anx { get; set; } + public string XnaAssembly { get; set; } + public string AnxAssembly { get; set; } + + public NamespaceMapping(string Xna, string Anx) + { + this.Xna = Xna; + this.Anx = Anx; + } + + public NamespaceMapping(string Xna, string Anx, string XnaAssembly, string AnxAssembly) + { + this.Xna = Xna; + this.Anx = Anx; + this.XnaAssembly = XnaAssembly; + this.AnxAssembly = AnxAssembly; + } + + public string GetInput(MappingDirection dir) + { + if (dir == MappingDirection.Xna2Anx) + { + return Xna; + } + else + { + return Anx; + } + } + + public string GetOutput(MappingDirection dir) + { + if (dir == MappingDirection.Xna2Anx) + { + return Anx; + } + else + { + return Xna; + } + } + } + + public enum MappingDirection + { + Xna2Anx, + Anx2Xna, + } + + internal class NamespaceMapper + { + private static string xnaPrefix = "Microsoft.Xna.Framework"; + private static string anxPrefix = "ANX.Framework"; + + private static NamespaceMapping[] mappings = new[] { new NamespaceMapping(xnaPrefix , anxPrefix , "Microsoft.Xna.Framework" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Avatar" , anxPrefix + ".Avatar" , "Microsoft.Xna.Framework.Avatar" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Graphics" , anxPrefix + ".Graphics" , "Microsoft.Xna.Framework.Graphics" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Input" , anxPrefix + ".Input" , "Microsoft.Xna.Framework" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Input.Touch" , anxPrefix + ".Input.Touch" , "Microsoft.Xna.Framework.Input.Touch" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Game" , anxPrefix + ".Game" , "Microsoft.Xna.Framework.Game" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".GamerServices" , anxPrefix + ".GamerServices" , "Microsoft.Xna.Framework.GamerServices", "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Net" , anxPrefix + ".Net" , "Microsoft.Xna.Framework.Net" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Storage" , anxPrefix + ".Storage" , "Microsoft.Xna.Framework.Storage" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Video" , anxPrefix + ".Video" , "Microsoft.Xna.Framework.Video" , "ANX.Framework"), + new NamespaceMapping(xnaPrefix + ".Xact" , anxPrefix + ".Xact" , "Microsoft.Xna.Framework.Xact" , "ANX.Framework"), + + new NamespaceMapping("", "ANX.InputDevices.OpenTK"), + new NamespaceMapping("", "ANX.InputDevices.PsVita"), + new NamespaceMapping("", "ANX.InputDevices.Test"), + new NamespaceMapping("", "ANX.InputDevices.Windows.Kinect"), + new NamespaceMapping("", "ANX.InputDevices.Windows.ModernUI"), + new NamespaceMapping("", "ANX.InputDevices.Windows.XInput"), + new NamespaceMapping("", "ANX.InputSystem.Recording"), + new NamespaceMapping("", "ANX.InputSystem.Standard"), + + new NamespaceMapping("", "ANX.PlatformSystem.Linux"), + new NamespaceMapping("", "ANX.PlatformSystem.Metro"), + new NamespaceMapping("", "ANX.PlatformSystem.PsVita"), + new NamespaceMapping("", "ANX.PlatformSystem.Windows"), + + new NamespaceMapping("", "ANX.RenderSystem.GL3"), + new NamespaceMapping("", "ANX.RenderSystem.PsVita"), + new NamespaceMapping("", "ANX.RenderSystem.Windows.DX10"), + new NamespaceMapping("", "ANX.RenderSystem.Windows.DX11"), + new NamespaceMapping("", "ANX.RenderSystem.Windows.Metro"), + + new NamespaceMapping("", "ANX.SoundSystem.OpenAL"), + new NamespaceMapping("", "ANX.SoundSystem.PsVita"), + new NamespaceMapping("", "ANX.SoundSystem.Windows.XAudio"), + + }; + + public static string TryMapNamespace(MappingDirection dir, string input) + { + foreach (NamespaceMapping mapping in mappings) + { + if (String.Equals(input, mapping.GetInput(dir), StringComparison.InvariantCultureIgnoreCase)) + { + return mapping.GetOutput(dir); + } + } + + return input; + } + + public static bool IsProjectReference(MappingDirection dir, string reference) + { + foreach (NamespaceMapping mapping in mappings) + { + if (String.Equals(reference, mapping.GetInput(dir), StringComparison.InvariantCultureIgnoreCase)) + { + return true; + } + } + + return false; + } + + public static string GetReferencingAssemblyName(MappingDirection dir, string reference) + { + foreach (NamespaceMapping mapping in mappings) + { + if (String.Equals(reference, mapping.GetInput(dir), StringComparison.InvariantCultureIgnoreCase)) + { + if (dir == MappingDirection.Xna2Anx) + { + return mapping.AnxAssembly; + } + else + { + return mapping.XnaAssembly; + } + } + } + + return string.Empty; + } + } +} diff --git a/Tools/ProjectConverter/Platforms/AbstractXna2AnxConverter.cs b/Tools/ProjectConverter/Platforms/AbstractXna2AnxConverter.cs index 4221df01..f0e63d9b 100644 --- a/Tools/ProjectConverter/Platforms/AbstractXna2AnxConverter.cs +++ b/Tools/ProjectConverter/Platforms/AbstractXna2AnxConverter.cs @@ -1,19 +1,33 @@ -using System; +#region Using Statements +using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Xml.Linq; + +#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 ProjectConverter.Platforms { public abstract class AbstractXna2AnxConverter : Converter { protected internal List csharpFiles = new List(); + protected internal HashSet filesToCopy = new HashSet(); + protected internal HashSet assemblyReferencesToAdd = new HashSet(); public override string Postfix { get { return string.Empty; } } + protected internal abstract MappingDirection MappingDirection { get; } + + protected internal abstract string ReplaceInlineNamespaces(string input); + protected override void ConvertItemGroup(System.Xml.Linq.XElement element) { var groups = element.Elements().ToList(); @@ -33,6 +47,18 @@ namespace ProjectConverter.Platforms } } } + else if (group.Name.LocalName.Equals("content", StringComparison.InvariantCultureIgnoreCase) || + group.Name.LocalName.Equals("none", StringComparison.InvariantCultureIgnoreCase)) + { + var attributes = group.Attributes().ToList(); + foreach (var attribute in attributes) + { + if (attribute.Name.LocalName.Equals("include", StringComparison.InvariantCultureIgnoreCase)) + { + filesToCopy.Add(attribute.Value); + } + } + } } base.ConvertItemGroup(element); @@ -40,19 +66,53 @@ namespace ProjectConverter.Platforms protected override void PostConvert() { + string destinationPath = System.IO.Path.GetDirectoryName(base.CurrentProject.FullDestinationPath); + foreach (var file in csharpFiles) { string target = string.Empty; ConvertUsingDirectives(file, ref target); + + string destinationFile = System.IO.Path.Combine(destinationPath, file); + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(destinationFile)); + System.IO.File.WriteAllText(destinationFile, ReplaceInlineNamespaces(target)); + } + + string namespaceName = CurrentProject.Root.Name.NamespaceName; + XName referenceName = XName.Get("Reference", namespaceName); + XName itemGroupName = XName.Get("ItemGroup", namespaceName); + var groups = CurrentProject.Root.Elements().ToList(); + + foreach (var group in groups) + { + if (group.Name == itemGroupName) + { + foreach (string reference in assemblyReferencesToAdd) + { + if (group.Element(GetXName("Reference")) != null) + { + var referenceElement = new XElement(GetXName("Reference")); + referenceElement.Add(new XAttribute("Include", reference)); + group.Add(referenceElement); + } + } + } + } + + foreach (var file in filesToCopy) + { + string destinationFile = System.IO.Path.Combine(destinationPath, file); + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(destinationFile)); + System.IO.File.Copy(System.IO.Path.Combine(CurrentProject.FullSourceDirectoryPath, file), destinationFile, true); } base.PostConvert(); } - protected abstract void ConvertUsingDirectives(string file, ref string target); - - protected void ConvertUsingDirectivesImpl(ref string content, ref string target, string sourceNamespace, string targetNamespace, string[] namespaces) + protected void ConvertUsingDirectives(string file, ref string target) { + string content = System.IO.File.ReadAllText(System.IO.Path.Combine(CurrentProject.FullSourceDirectoryPath, file)); + int lastPos = 0; int currentPos = -1; int endPos = 0; @@ -64,14 +124,11 @@ namespace ProjectConverter.Platforms if (currentPos >= 0) { endPos = NextTokenPos(ref content, currentPos + tokenLength, ref tokenLength); - string directive = content.Substring(currentPos + 5, endPos - currentPos - 5); + string directive = content.Substring(currentPos + 6, endPos - currentPos - 6); target += content.Substring(lastPos, (currentPos + 6) - lastPos); - if (namespaces.Contains(directive.Trim())) - { - directive = directive.Replace(sourceNamespace, targetNamespace); - } + directive = NamespaceMapper.TryMapNamespace(MappingDirection, directive); target += directive; lastPos = endPos; diff --git a/Tools/ProjectConverter/Platforms/AnxConverter.cs b/Tools/ProjectConverter/Platforms/AnxConverter.cs index cbe21473..f8865927 100644 --- a/Tools/ProjectConverter/Platforms/AnxConverter.cs +++ b/Tools/ProjectConverter/Platforms/AnxConverter.cs @@ -2,40 +2,55 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Xml.Linq; +using System.IO; namespace ProjectConverter.Platforms { public class AnxConverter : AbstractXna2AnxConverter { - private readonly string[] xnaNamespaces = new string[] { "Microsoft.XNA.Framework", - "Microsoft.XNA.Framework.Avatar", - "Microsoft.XNA.Framework.Content.Pipeline.AudioImporters", - "Microsoft.XNA.Framework.Content.Pipeline", - "Microsoft.XNA.Framework.Content.Pipeline.EffectImporter", - "Microsoft.XNA.Framework.Content.Pipeline.FBXImporter", - "Microsoft.XNA.Framework.Content.Pipeline.TextureImporter", - "Microsoft.XNA.Framework.Content.Pipeline.VideoImporters", - "Microsoft.XNA.Framework.Content.Pipeline.XImporter", - "Microsoft.XNA.Framework.Game", - "Microsoft.XNA.Framework.GamerServices", - "Microsoft.XNA.Framework.Graphics", - "Microsoft.XNA.Framework.Input", - "Microsoft.XNA.Framework.Input.Touch", - "Microsoft.XNA.Framework.Net", - "Microsoft.XNA.Framework.Storage", - "Microsoft.XNA.Framework.Video", - "Microsoft.XNA.Framework.Xact", - }; + public AnxConverter() + { + // add default XNA references + assemblyReferencesToAdd.Add("Microsoft.Xna.Framework"); + assemblyReferencesToAdd.Add("Microsoft.Xna.Framework.Game"); + assemblyReferencesToAdd.Add("Microsoft.Xna.Framework.Input"); + assemblyReferencesToAdd.Add("Microsoft.Xna.Framework.Graphics"); + } public override string Name { get { return "anx2xna"; } } - protected override void ConvertUsingDirectives(string file, ref string target) + protected internal override MappingDirection MappingDirection { - string content = System.IO.File.ReadAllText(System.IO.Path.Combine(CurrentProject.FullSourceDirectoryPath, file)); - ConvertUsingDirectivesImpl(ref content, ref target, "Microsoft.XNA.Framework", "ANX.Framework", xnaNamespaces); + get { return ProjectConverter.MappingDirection.Anx2Xna; } + } + + protected override void ConvertProjectReference(XElement element) + { + XAttribute includeAttribute = element.Attribute("Include"); + if (includeAttribute != null) + { + string reference = Path.GetFileNameWithoutExtension(includeAttribute.Value); // sometimes the node contains a relative path to the reference + + if (NamespaceMapper.IsProjectReference(MappingDirection, reference)) + { + string referenceAssembly = NamespaceMapper.GetReferencingAssemblyName(MappingDirection, reference); + if (!string.IsNullOrEmpty(referenceAssembly)) + { + assemblyReferencesToAdd.Add(referenceAssembly); + } + + element.Remove(); + } + } + } + + protected internal override string ReplaceInlineNamespaces(string input) + { + return input.Replace("ANX.Framework.Game", "Microsoft.Xna.Framework.Game"); } } } diff --git a/Tools/ProjectConverter/Platforms/XnaConverter.cs b/Tools/ProjectConverter/Platforms/XnaConverter.cs index 621f1ad3..d2d13a04 100644 --- a/Tools/ProjectConverter/Platforms/XnaConverter.cs +++ b/Tools/ProjectConverter/Platforms/XnaConverter.cs @@ -1,41 +1,34 @@ -using System; +#region Using Statements +using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Xml.Linq; + +#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 ProjectConverter.Platforms { public class XnaConverter : AbstractXna2AnxConverter { - private readonly string[] anxNamespaces = new string[] { "ANX.Framework", - "ANX.Framework.Avatar", - "ANX.Framework.Content.Pipeline.AudioImporters", - "ANX.Framework.Content.Pipeline", - "ANX.Framework.Content.Pipeline.EffectImporter", - "ANX.Framework.Content.Pipeline.FBXImporter", - "ANX.Framework.Content.Pipeline.TextureImporter", - "ANX.Framework.Content.Pipeline.VideoImporters", - "ANX.Framework.Content.Pipeline.XImporter", - "ANX.Framework.Game", - "ANX.Framework.GamerServices", - "ANX.Framework.Graphics", - "ANX.Framework.Input", - "ANX.Framework.Input.Touch", - "ANX.Framework.Net", - "ANX.Framework.Storage", - "ANX.Framework.Video", - "ANX.Framework.Xact", - }; - public override string Name { get { return "xna2anx"; } } - protected override void ConvertUsingDirectives(string file, ref string target) + protected internal override MappingDirection MappingDirection { - string content = System.IO.File.ReadAllText(System.IO.Path.Combine(CurrentProject.FullSourceDirectoryPath, file)); - ConvertUsingDirectivesImpl(ref content, ref target, "ANX.Framework", "Microsoft.XNA.Framework", anxNamespaces); + get { return ProjectConverter.MappingDirection.Xna2Anx; } } + + protected internal override string ReplaceInlineNamespaces(string input) + { + return input.Replace("Microsoft.Xna.Framework.Game", "ANX.Framework.Game"); + } + } } diff --git a/Tools/ProjectConverter/ProjectConverter.csproj b/Tools/ProjectConverter/ProjectConverter.csproj index 18b251f9..ac18f635 100644 --- a/Tools/ProjectConverter/ProjectConverter.csproj +++ b/Tools/ProjectConverter/ProjectConverter.csproj @@ -48,6 +48,7 @@ +