diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentCompiler.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentCompiler.cs index 5e9a30d3..771debc1 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentCompiler.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentCompiler.cs @@ -71,10 +71,9 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler { compressContent = this.ShouldCompressContent(targetPlatform, value); } - using (ContentWriter contentWriter = new ContentWriter(this, output, targetPlatform, targetProfile, compressContent, rootDirectory, referenceRelocationPath)) + using (ContentWriter contentWriter = new ContentWriter(this, output, compressContent, rootDirectory, referenceRelocationPath) { TargetPlatform = targetPlatform, TargetProfile = targetProfile }) { contentWriter.WriteObject(value); - contentWriter.FlushOutput(); } } diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentTypeWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentTypeWriter.cs index 59c9e476..68f1e8df 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentTypeWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentTypeWriter.cs @@ -14,6 +14,7 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler { private bool canDeserializeIntoExistingObject; private Type targetType; + internal readonly bool TargetIsValueType; protected ContentTypeWriter(Type targetType) { @@ -140,7 +141,7 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler { get { - throw new NotImplementedException(); + return 0; } } } diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs index 59896b0e..a2d65e7e 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/ContentWriter.cs @@ -16,33 +16,35 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler { public sealed class ContentWriter : BinaryWriter { - private TargetPlatform targetPlatform; - private GraphicsProfile targetProfile; + #region Private Members private ContentCompiler compiler; - private MemoryStream headerData; - private MemoryStream contentData; - private Stream finalOutput; private Boolean compressContent; private string rootDirectory; private string referenceRelocationPath; + private Dictionary typeTable = new Dictionary(); + private List typeWriters = new List(); + + private Stream outputStream; + private MemoryStream header = new MemoryStream(); + private MemoryStream content = new MemoryStream(); + + #endregion const byte xnbFormatVersion = (byte)5; char[] xnbMagicWord = new char[] { 'X', 'N', 'B' }; - internal ContentWriter(ContentCompiler compiler, Stream output, TargetPlatform targetPlatform, GraphicsProfile targetProfile, bool compressContent, string rootDirectory, string referenceRelocationPath) + internal ContentWriter(ContentCompiler compiler, Stream output, bool compressContent, string rootDirectory, string referenceRelocationPath) { this.compiler = compiler; - this.targetPlatform = targetPlatform; - this.targetProfile = targetProfile; this.compressContent = compressContent; this.rootDirectory = rootDirectory; this.referenceRelocationPath = referenceRelocationPath; - this.finalOutput = output; - this.headerData = new MemoryStream(); - this.contentData = new MemoryStream(); - this.OutStream = this.contentData; + + this.outputStream = output; + this.OutStream = content; } + #region Write value types public void Write(Color value) { base.Write(value.PackedValue); @@ -97,9 +99,17 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler base.Write(value.W); } + #endregion + public void WriteExternalReference(ExternalReference reference) { - throw new NotImplementedException(); + if (reference == null || String.IsNullOrEmpty(reference.Filename)) + { + Write(String.Empty); + return; + } + + Write(Path.GetFileNameWithoutExtension(reference.Filename)); } public void WriteObject(T value) @@ -110,19 +120,107 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler return; } - ContentTypeWriter typeWriter = this.compiler.GetTypeWriter(value.GetType()); + int typeIndex; + ContentTypeWriter typeWriter = this.GetTypeWriter(value.GetType(), out typeIndex); + base.Write7BitEncodedInt(typeIndex + 1); - base.Write7BitEncodedInt(1); - //if (this.recurseDetector.ContainsKey(value)) - //{ - // throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.FoundCyclicReference, new object[] - // { - // value - // })); - //} - //this.recurseDetector.Add(value, true); + //TODO: test for recursive cyclic calls this.InvokeWriter(value, typeWriter); - //this.recurseDetector.Remove(value); + } + + public void WriteObject(T value, ContentTypeWriter typeWriter) + { + if (value == null) + { + base.Write7BitEncodedInt(0); + return; + } + + if (typeWriter.TargetIsValueType) + { + this.InvokeWriter(value, typeWriter); + return; + } + + this.WriteObject(value); + } + + public void WriteRawObject(T value) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + int typeIndex; + ContentTypeWriter typeWriter = this.GetTypeWriter(typeof(T), out typeIndex); + this.InvokeWriter(value, typeWriter); + } + + public void WriteRawObject(T value, ContentTypeWriter typeWriter) + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + if (typeWriter == null) + { + throw new ArgumentNullException("typeWriter"); + } + this.InvokeWriter(value, typeWriter); + } + + public void WriteSharedResource(T value) + { + throw new NotImplementedException(); + } + + public TargetPlatform TargetPlatform + { + get; + set; + } + + public GraphicsProfile TargetProfile + { + get; + set; + } + + protected override void Dispose(bool disposing) + { + WriteData(); + + base.Dispose(disposing); + } + + private void WriteData() + { + OutStream = header; + Write7BitEncodedInt(this.typeWriters.Count); + foreach (ContentTypeWriter current in this.typeWriters) + { + Write(current.GetRuntimeReader(TargetPlatform)); + Write(current.TypeVersion); + } + Write7BitEncodedInt((int)0); // number of shared resources + //TODO: write shared resources + + + OutStream = outputStream; + + Write(xnbMagicWord); // magic bytes for file recognition - 03 bytes + Write((byte)TargetPlatform); // target platform of content file - 01 byte + Write((byte)xnbFormatVersion); // version of this file - 01 byte + Write((byte)(TargetProfile == GraphicsProfile.HiDef ? 0x01 : 0x00)); // flags - 01 byte + Write((int)header.Length + (int)content.Length + 10); // size of file - 04 byte + if (compressContent) + { + //TODO: write compressed size + } + + OutStream.Write(header.GetBuffer(), 0, (int)header.Length); + OutStream.Write(content.GetBuffer(), 0, (int)content.Length); //TODO: write compressed stream if compressedContent is true } private void InvokeWriter(T value, ContentTypeWriter writer) @@ -136,94 +234,30 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler writer.Write(this, value); } - public void WriteObject(T value, ContentTypeWriter typeWriter) + private ContentTypeWriter GetTypeWriter(Type type, out int typeIndex) { - throw new NotImplementedException(); - } + if (this.typeTable.TryGetValue(type, out typeIndex)) + { + return this.typeWriters[typeIndex]; + } - public void WriteRawObject(T value) - { - throw new NotImplementedException(); - } + IEnumerable enumerable = null; + ContentTypeWriter typeWriter = this.compiler.GetTypeWriter(type); //TODO:, out enumerable); + typeIndex = this.typeWriters.Count; + this.typeWriters.Add(typeWriter); + this.typeTable.Add(type, typeIndex); - public void WriteRawObject(T value, ContentTypeWriter typeWriter) - { - throw new NotImplementedException(); - } - - public void WriteSharedResource(T value) - { - throw new NotImplementedException(); - } - - internal void FlushOutput() - { - //TODO: implement - - //this.WriteSharedResources(); - this.WriteHeader(); - this.WriteFinalOutput(); - } - - private void WriteHeader() - { - this.OutStream = this.headerData; - //TODO: implement - //base.Write7BitEncodedInt(this.typeWriters.Count); - //foreach (ContentTypeWriter current in this.typeWriters) + //TODO: what is this for? + //foreach (Type current in enumerable) //{ - // this.Write(current.GetRuntimeReader(this.targetPlatform)); - // this.Write(current.TypeVersion); + // if (!(current == typeof(object))) + // { + // int num; + // this.GetTypeWriter(current, out num); + // } //} - //base.Write7BitEncodedInt(this.sharedResourceNames.Count); - } - private void WriteFinalOutput() - { - this.OutStream = this.finalOutput; - this.Write(xnbMagicWord); - this.Write((byte)this.targetPlatform); - if (this.compressContent) - { - throw new NotImplementedException(); - //this.WriteCompressedOutput(); - } - else - { - this.WriteUncompressedOutput(); - } - } - - private void WriteUncompressedOutput() - { - this.Write(xnbFormatVersion); // Version - - byte flags = 0; - if (TargetProfile == GraphicsProfile.HiDef) - { - flags |= 0x01; - } - this.Write(flags); - - this.Write(10 + this.headerData.Length + this.contentData.Length); - this.OutStream.Write(this.headerData.GetBuffer(), 0, (int)this.headerData.Length); - this.OutStream.Write(this.contentData.GetBuffer(), 0, (int)this.contentData.Length); - } - - public TargetPlatform TargetPlatform - { - get - { - return targetPlatform; - } - } - - public GraphicsProfile TargetProfile - { - get - { - return targetProfile; - } + return typeWriter; } } } diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GenericContentTypeWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GenericContentTypeWriter.cs index 01c8e4eb..03acce76 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GenericContentTypeWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GenericContentTypeWriter.cs @@ -19,28 +19,16 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler protected internal override void Write(ContentWriter output, object value) { - this.Write(output, ContentTypeWriter.CastType(value)); + if (value is T) + { + this.Write(output, (T)value); + } + else + { + throw new FormatException("The type of the value-object does not match the generic T-parameter"); + } } protected internal abstract void Write(ContentWriter output, T value); - - private static T CastType(object value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - if (!(value is T)) - { - System.Diagnostics.Debugger.Break(); - //throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.WrongArgumentType, new object[] - //{ - // typeof(T), - // value.GetType() - //})); - } - return (T)((object)value); - } - } } diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs index 59ceca23..d51e59ab 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs @@ -28,11 +28,11 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler protected internal override void Write(ContentWriter output, CompiledEffectContent value) { - //TODO: implement - //if (output.TargetPlatform == TargetPlatform.WindowsPhone) - //{ - // throw new InvalidContentException(Resources.MobileNoEffects); - //} + if (output.TargetPlatform != TargetPlatform.Windows) + { + throw new InvalidOperationException("currently only HLSL windows effects are supported by EffectWriter"); + } + byte[] effectCode = value.GetEffectCode(); output.Write(effectCode.Length); output.Write(effectCode); diff --git a/ANX.Framework.Content.Pipeline/TargetPlatform.cs b/ANX.Framework.Content.Pipeline/TargetPlatform.cs index d8f20bd4..034f562c 100644 --- a/ANX.Framework.Content.Pipeline/TargetPlatform.cs +++ b/ANX.Framework.Content.Pipeline/TargetPlatform.cs @@ -11,8 +11,17 @@ namespace ANX.Framework.Content.Pipeline { public enum TargetPlatform : byte { - Windows = (byte)119, - WindowsPhone = (byte)109, - XBox360 = (byte)120, + Windows = (byte)'w', + WindowsPhone = (byte)'m', + XBox360 = (byte)'x', + + // ANX-Extensions + Android = (byte)'a', + IOS = (byte)'i', + Linux = (byte)'l', + MacOs = (byte)'o', + PsVita = (byte)'p', + WindowsMetro = (byte)'8', + } } diff --git a/Tools/XNBInspector/InspectReader.cs b/Tools/XNBInspector/InspectReader.cs index 3c3703cc..0fa797cc 100644 --- a/Tools/XNBInspector/InspectReader.cs +++ b/Tools/XNBInspector/InspectReader.cs @@ -78,6 +78,13 @@ namespace ANX.Tools.XNBInspector // w = Microsoft Windows // m = Windows Phone 7 // x = Xbox 360 + // ANX-EXTENSIONS: + // a = Android + // i = iOS + // l = Linux + // o = MacOs + // p = PS Vita / Mobile + // 8 = Windows 8 Metro result.Append(Severity.None, "Target platform : "); switch ((char)targetPlattform) { @@ -90,8 +97,26 @@ namespace ANX.Tools.XNBInspector case 'x': result.AppendFormat(Severity.Success, "{0}[x] (Xbox 360)", targetPlattform); break; + case 'a': + result.AppendFormat(Severity.Success, "{0}[a] (Android) | ANX extension", targetPlattform); + break; + case 'i': + result.AppendFormat(Severity.Success, "{0}[i] (iOS) | ANX extension", targetPlattform); + break; + case 'l': + result.AppendFormat(Severity.Success, "{0}[l] (Linux) | ANX extension", targetPlattform); + break; + case 'o': + result.AppendFormat(Severity.Success, "{0}[o] (MacOS) | ANX extension", targetPlattform); + break; + case 'p': + result.AppendFormat(Severity.Success, "{0}[p] (PS Vita / mobile) | ANX extension", targetPlattform); + break; + case '8': + result.AppendFormat(Severity.Success, "{0}[8] (Windows 8 metro) | ANX extension", targetPlattform); + break; default: - result.AppendFormat(Severity.Error, "{0} (Unknown or non XNA platform)", targetPlattform); + result.AppendFormat(Severity.Error, "{0} (Unknown or non XNA/ANX platform)", targetPlattform); break; } result.AppendLine(); diff --git a/Tools/XNBInspector/Properties/AssemblyInfo.cs b/Tools/XNBInspector/Properties/AssemblyInfo.cs index c9becaf6..d73a14a7 100644 --- a/Tools/XNBInspector/Properties/AssemblyInfo.cs +++ b/Tools/XNBInspector/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.3.0.0")] -[assembly: AssemblyFileVersion("0.3.0.0")] +[assembly: AssemblyVersion("0.3.1.0")] +[assembly: AssemblyFileVersion("0.3.1.0")]