Duplicate enums are now dropped (Core > ARB > EXT > Vendor-specific).

Final values are calculated for all tokens (no "Foo = (int)Bar.Baz" anymore)
EnumCollection keys are now updated after translating the enums.
This commit is contained in:
the_fiddler 2008-01-03 00:08:49 +00:00
parent e56a9500ec
commit 0f15148926
2 changed files with 155 additions and 21 deletions

View file

@ -34,6 +34,7 @@ namespace Bind.Structures
{ {
if (!String.IsNullOrEmpty(value)) if (!String.IsNullOrEmpty(value))
_name = Translate(value.Trim()); _name = Translate(value.Trim());
else _name = value;
} }
} }
@ -48,11 +49,25 @@ namespace Bind.Structures
/// </summary> /// </summary>
public string Value 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 set
{ {
if (!String.IsNullOrEmpty(value)) if (!String.IsNullOrEmpty(value))
_value = Translate(value.Trim()); _value = Translate(value.Trim());
else _value = value;
} }
} }
@ -73,6 +88,7 @@ namespace Bind.Structures
{ {
if (!String.IsNullOrEmpty(value)) if (!String.IsNullOrEmpty(value))
_reference = Enum.TranslateName(value.Trim()); _reference = Enum.TranslateName(value.Trim());
else _reference = value;
} }
} }
@ -112,9 +128,9 @@ namespace Bind.Structures
#endregion #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); translator.Remove(0, translator.Length);
@ -139,12 +155,41 @@ namespace Bind.Structures
else else
translator.Append(s); translator.Append(s);
return translator.ToString(); return translator.ToString();
} }
#endregion #endregion
/// <summary>
/// Replces the Value of the given constant with the value referenced by the [c.Reference, c.Value] pair.
/// </summary>
/// <param name="c">The Constant to translate</param>
/// <param name="enums">The list of enums to check.</param>
/// <param name="auxEnums">The list of auxilliary enums to check.</param>
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() #region public override string ToString()
/// <summary> /// <summary>
@ -154,13 +199,13 @@ namespace Bind.Structures
/// <returns></returns> /// <returns></returns>
public override string ToString() public override string ToString()
{ {
return String.Format( if (String.IsNullOrEmpty(Name))
"{0} = {1}((int){2}{3})", return "";
Name, return String.Format("{0} = {1}((int){2}{3})",
Unchecked ? "unchecked" : "", Name, Unchecked ? "unchecked" : "",
!String.IsNullOrEmpty(Reference) ? Reference + "." : "", !String.IsNullOrEmpty(Reference) ? Reference + "." : "", Value);
Value
); //return String.Format("{0} = {1}((int){2})", Name, Unchecked ? "unchecked" : "", Value);
} }
#endregion #endregion

View file

@ -15,8 +15,8 @@ namespace Bind.Structures
public class Enum public class Enum
{ {
internal static EnumCollection GLEnums; internal static EnumCollection GLEnums = new EnumCollection();
internal static EnumCollection AuxEnums; internal static EnumCollection AuxEnums = new EnumCollection();
static StringBuilder translator = new StringBuilder(); static StringBuilder translator = new StringBuilder();
string _name; string _name;
@ -57,6 +57,7 @@ namespace Bind.Structures
} }
} }
} }
enumsLoaded = true; enumsLoaded = true;
} }
} }
@ -75,12 +76,16 @@ namespace Bind.Structures
#endregion #endregion
#region public string Name
public string Name public string Name
{ {
get { return _name; } get { return _name; }
set { _name = value; } set { _name = value; }
} }
#endregion
System.Collections.Hashtable _constant_collection = new System.Collections.Hashtable(); System.Collections.Hashtable _constant_collection = new System.Collections.Hashtable();
public System.Collections.Hashtable ConstantCollection 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 bool is_after_underscore = true; // Detect if we just passed a '_' and make the next char
// uppercase. // 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. // the current one to lowercase.
foreach (char c in name) foreach (char c in name)
@ -136,6 +141,7 @@ namespace Bind.Structures
{ {
sb.Append(" "); sb.Append(" ");
sb.Append(c.ToString()); sb.Append(c.ToString());
if (!String.IsNullOrEmpty(c.ToString()))
sb.AppendLine(","); sb.AppendLine(",");
} }
sb.Append("}"); sb.Append("}");
@ -148,20 +154,38 @@ namespace Bind.Structures
#region class EnumCollection #region class EnumCollection
class EnumCollection : Dictionary<string, Enum> public class EnumCollection : Dictionary<string, Enum>
{ {
internal void AddRange(EnumCollection enums) internal void AddRange(EnumCollection enums)
{ {
foreach (Enum e in enums.Values) foreach (Enum e in enums.Values)
{
Utilities.Merge(this, e); Utilities.Merge(this, e);
} }
}
internal void Translate() internal void Translate()
{ {
// Translate enum names.
{
List<string> keys_to_update = new List<string>();
foreach (Enum e in this.Values) foreach (Enum e in this.Values)
e.Name = Enum.TranslateName(e.Name); {
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 (Enum e in this.Values)
{ {
@ -181,11 +205,76 @@ namespace Bind.Structures
if (@enum.ConstantCollection.ContainsKey(c.Value)) if (@enum.ConstantCollection.ContainsKey(c.Value))
{ {
c.Reference = @enum.Name; 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) new bool TryGetValue(string key, out Enum value)