Implemented first working version of ANX to XNA project transformation using the ProjectConverter tool. The other way round is not tested yet but should work too.

Translation of content projects is missing but this will be the next one...
This commit is contained in:
Glatzemann 2012-10-24 15:09:16 +00:00 committed by Konstantin Koch
parent bf101259fe
commit 87dd600ffe
5 changed files with 277 additions and 55 deletions

View File

@ -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;
}
}
}

View File

@ -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<string> csharpFiles = new List<string>();
protected internal HashSet<string> filesToCopy = new HashSet<string>();
protected internal HashSet<string> assemblyReferencesToAdd = new HashSet<string>();
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<string>(directive.Trim()))
{
directive = directive.Replace(sourceNamespace, targetNamespace);
}
directive = NamespaceMapper.TryMapNamespace(MappingDirection, directive);
target += directive;
lastPos = endPos;

View File

@ -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");
}
}
}

View File

@ -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");
}
}
}

View File

@ -48,6 +48,7 @@
<Compile Include="AssemblyInfoFixer.cs" />
<Compile Include="Converter.cs" />
<Compile Include="DefinesConverter.cs" />
<Compile Include="NamespaceMapper.cs" />
<Compile Include="Platforms\AbstractXna2AnxConverter.cs" />
<Compile Include="Platforms\AnxConverter.cs" />
<Compile Include="Platforms\XnaConverter.cs" />