diff --git a/Source/Bind/Structures/Constant.cs b/Source/Bind/Structures/Constant.cs index dc4b5793..bf740649 100644 --- a/Source/Bind/Structures/Constant.cs +++ b/Source/Bind/Structures/Constant.cs @@ -34,6 +34,7 @@ namespace Bind.Structures { if (!String.IsNullOrEmpty(value)) _name = Translate(value.Trim()); + else _name = value; } } @@ -48,11 +49,25 @@ namespace Bind.Structures /// public string Value { - get { return _value; } + get + { + //if (String.IsNullOrEmpty(Reference)) + // return _value; + //else + //{ + // Enum @ref; + // if (Enum.GLEnums.TryGetValue(Reference, out @ref) || Enum.AuxEnums.TryGetValue(Reference, out @ref)) + // if (@ref.ConstantCollection.ContainsKey(_value)) + // return (@ref.ConstantCollection[_value] as Constant).Value; + //} + + return _value; + } set { if (!String.IsNullOrEmpty(value)) _value = Translate(value.Trim()); + else _value = value; } } @@ -73,6 +88,7 @@ namespace Bind.Structures { if (!String.IsNullOrEmpty(value)) _reference = Enum.TranslateName(value.Trim()); + else _reference = value; } } @@ -112,9 +128,9 @@ namespace Bind.Structures #endregion - #region string Translate(string s) + #region public static string Translate(string s) - string Translate(string s) + public static string Translate(string s) { translator.Remove(0, translator.Length); @@ -139,12 +155,41 @@ namespace Bind.Structures else translator.Append(s); - return translator.ToString(); } #endregion + /// + /// Replces the Value of the given constant with the value referenced by the [c.Reference, c.Value] pair. + /// + /// The Constant to translate + /// The list of enums to check. + /// The list of auxilliary enums to check. + public static void TranslateConstantWithReference(Constant c, EnumCollection enums, EnumCollection auxEnums) + { + if (!String.IsNullOrEmpty(c.Reference)) + { + string value; + + if (enums[c.Reference].ConstantCollection.ContainsKey(c.Value)) + { + TranslateConstantWithReference(enums[c.Reference].ConstantCollection[c.Value] as Constant, enums, auxEnums); + value = (enums[c.Reference].ConstantCollection[c.Value] as Constant).Value; + } + else if (auxEnums[c.Reference].ConstantCollection.ContainsKey(c.Value)) + { + TranslateConstantWithReference(auxEnums[c.Reference].ConstantCollection[c.Value] as Constant, enums, auxEnums); + value = (auxEnums[c.Reference].ConstantCollection[c.Value] as Constant).Value; + } + else throw new InvalidOperationException(String.Format("Unknown Enum \"{0}\" referenced by Constant \"{1}\"", + c.Reference, c.ToString())); + + c.Value = value; + c.Reference = null; + } + } + #region public override string ToString() /// @@ -154,13 +199,13 @@ namespace Bind.Structures /// public override string ToString() { - return String.Format( - "{0} = {1}((int){2}{3})", - Name, - Unchecked ? "unchecked" : "", - !String.IsNullOrEmpty(Reference) ? Reference + "." : "", - Value - ); + if (String.IsNullOrEmpty(Name)) + return ""; + return String.Format("{0} = {1}((int){2}{3})", + Name, Unchecked ? "unchecked" : "", + !String.IsNullOrEmpty(Reference) ? Reference + "." : "", Value); + + //return String.Format("{0} = {1}((int){2})", Name, Unchecked ? "unchecked" : "", Value); } #endregion diff --git a/Source/Bind/Structures/Enum.cs b/Source/Bind/Structures/Enum.cs index 97d77f60..50d8d258 100644 --- a/Source/Bind/Structures/Enum.cs +++ b/Source/Bind/Structures/Enum.cs @@ -15,8 +15,8 @@ namespace Bind.Structures public class Enum { - internal static EnumCollection GLEnums; - internal static EnumCollection AuxEnums; + internal static EnumCollection GLEnums = new EnumCollection(); + internal static EnumCollection AuxEnums = new EnumCollection(); static StringBuilder translator = new StringBuilder(); string _name; @@ -57,6 +57,7 @@ namespace Bind.Structures } } } + enumsLoaded = true; } } @@ -75,12 +76,16 @@ namespace Bind.Structures #endregion + #region public string Name + public string Name { get { return _name; } set { _name = value; } } + #endregion + System.Collections.Hashtable _constant_collection = new System.Collections.Hashtable(); public System.Collections.Hashtable ConstantCollection @@ -98,7 +103,7 @@ namespace Bind.Structures { bool is_after_underscore = true; // Detect if we just passed a '_' and make the next char // uppercase. - bool is_previous_uppercase = false; // Detetc if previous character was uppercase, and turn + bool is_previous_uppercase = false; // Detect if previous character was uppercase, and turn // the current one to lowercase. foreach (char c in name) @@ -136,7 +141,8 @@ namespace Bind.Structures { sb.Append(" "); sb.Append(c.ToString()); - sb.AppendLine(","); + if (!String.IsNullOrEmpty(c.ToString())) + sb.AppendLine(","); } sb.Append("}"); @@ -148,21 +154,39 @@ namespace Bind.Structures #region class EnumCollection - class EnumCollection : Dictionary + public class EnumCollection : Dictionary { internal void AddRange(EnumCollection enums) { foreach (Enum e in enums.Values) - { Utilities.Merge(this, e); - } } internal void Translate() { - foreach (Enum e in this.Values) - e.Name = Enum.TranslateName(e.Name); - + // Translate enum names. + { + List keys_to_update = new List(); + foreach (Enum e in this.Values) + { + string name = Enum.TranslateName(e.Name); + if (name != e.Name) + { + keys_to_update.Add(e.Name); + e.Name = name; + } + } + + foreach (string name in keys_to_update) + { + Enum e = this[name]; + this.Remove(name); + this.Add(e.Name, e); + } + + keys_to_update = null; + } + foreach (Enum e in this.Values) { foreach (Constant c in e.ConstantCollection.Values) @@ -181,11 +205,76 @@ namespace Bind.Structures if (@enum.ConstantCollection.ContainsKey(c.Value)) { c.Reference = @enum.Name; + break; } } } } } + + foreach (Enum e in this.Values) + foreach (Constant c in e.ConstantCollection.Values) + Constant.TranslateConstantWithReference(c, Enum.GLEnums, Enum.AuxEnums); + + // When there are multiple tokens with the same value but different extension + // drop the duplicates. Order of preference: core > ARB > EXT > vendor specific + foreach (Enum e in this.Values) + { + if (e.Name == "All") + continue; + + foreach (Constant c in e.ConstantCollection.Values) + foreach (Constant c2 in e.ConstantCollection.Values) + { + if (c.Name != c2.Name && c.Value == c2.Value) + { + if (c.Name.Contains(Constant.Translate("TEXTURE_DEFORMATION_BIT_SGIX")) || + c2.Name.Contains(Constant.Translate("TEXTURE_DEFORMATION_BIT_SGIX"))) + { + } + + int prefer = OrderOfPreference(Utilities.GetGL2Extension(c.Name), Utilities.GetGL2Extension(c2.Name)); + if (prefer == -1) + { + c2.Name = ""; + c2.Value = ""; + } + else if (prefer == 1) + { + c.Name = ""; + c.Value = ""; + } + } + } + } + } + + // Return -1 for ext1, 1 for ext2 or 0 if no preference. + int OrderOfPreference(string ext1, string ext2) + { + // If one is empty and the other note, prefer the empty one. + // (empty == core) + // Otherwise check for Arb and Ext. To reuse the logic for the + // empty check, let's try to remove first Arb, then Ext from the strings. + int ret; + ret = OrderOfPreferenceInternal(ext1, ext2); + if (ret != 0) return ret; + ext1 = ext1.Replace("Arb", ""); ext2 = ext2.Replace("Arb", ""); + ret = OrderOfPreferenceInternal(ext1, ext2); + if (ret != 0) return ret; + ext1 = ext1.Replace("Ext", ""); ext2 = ext2.Replace("Ext", ""); + return ret; + } + + // Prefer the empty string over the non-empty. + int OrderOfPreferenceInternal(string ext1, string ext2) + { + if (String.IsNullOrEmpty(ext1) && !String.IsNullOrEmpty(ext2)) + return -1; + else if (String.IsNullOrEmpty(ext2) && !String.IsNullOrEmpty(ext1)) + return 1; + else + return 0; } new bool TryGetValue(string key, out Enum value)