Avoid singletons; Translate*() in FuncProcessor

This is part of a long-due source cleanup series. All Translate*()
methods are now part of the FuncProcessor. Additionally, ToString() has
been improved and the IEquatable interface is now implemented.
ParameterCollection now has better control of when its cache should be
rebuilt.
This commit is contained in:
Stefanos A. 2013-11-01 09:13:06 +01:00
parent 83c0deb71c
commit f83443d221

View file

@ -15,11 +15,9 @@ namespace Bind.Structures
/// <summary> /// <summary>
/// Represents a single parameter of an opengl function. /// Represents a single parameter of an opengl function.
/// </summary> /// </summary>
class Parameter : Type, IComparable<Parameter> class Parameter : Type, IComparable<Parameter>, IEquatable<Parameter>
{ {
string cache; string cache;
bool rebuild;
bool unsafe_allowed; // True if the cache may contain unsafe types, false otherwise.
#region Constructors #region Constructors
@ -75,10 +73,7 @@ namespace Bind.Structures
{ {
get get
{ {
if (Utilities.Keywords.Contains(RawName)) return RawName;
return Settings.KeywordEscapeCharacter + RawName;
else
return RawName;
} }
set set
{ {
@ -90,7 +85,6 @@ namespace Bind.Structures
value = value.Substring(1); value = value.Substring(1);
} }
RawName = value; RawName = value;
rebuild = true;
} }
} }
} }
@ -111,7 +105,6 @@ namespace Bind.Structures
if (_unmanaged_type != value) if (_unmanaged_type != value)
{ {
_unmanaged_type = value; _unmanaged_type = value;
rebuild = true;
} }
} }
} }
@ -133,7 +126,6 @@ namespace Bind.Structures
if (_flow != value) if (_flow != value)
{ {
_flow = value; _flow = value;
rebuild = true;
} }
} }
} }
@ -165,7 +157,6 @@ namespace Bind.Structures
if (_unchecked != value) if (_unchecked != value)
{ {
_unchecked = value; _unchecked = value;
rebuild = true;
} }
} }
} }
@ -183,23 +174,6 @@ namespace Bind.Structures
#endregion #endregion
#region public override string CurrentType
public override string CurrentType
{
get
{
return base.CurrentType;
}
set
{
base.CurrentType = value;
rebuild = true;
}
}
#endregion
#region public bool DiffersOnlyOnReference #region public bool DiffersOnlyOnReference
// Returns true if this parameter differs only on reference compared to another parameter, i.e: // Returns true if this parameter differs only on reference compared to another parameter, i.e:
@ -218,153 +192,6 @@ namespace Bind.Structures
#endregion #endregion
#region public override string ToString()
public override string ToString()
{
return ToString(false);
}
#endregion
#region public string ToString(bool override_unsafe_setting)
public string ToString(bool override_unsafe_setting)
{
rebuild |= unsafe_allowed |= override_unsafe_setting;
unsafe_allowed = override_unsafe_setting;
if (!String.IsNullOrEmpty(cache) && !rebuild)
{
return cache;
}
else
{
StringBuilder sb = new StringBuilder();
if (Flow == FlowDirection.Out)
sb.Append("[OutAttribute] ");
else if (Flow == FlowDirection.Undefined)
sb.Append("[InAttribute, OutAttribute] ");
if (Reference)
{
if (Flow == FlowDirection.Out)
sb.Append("out ");
else
sb.Append("ref ");
}
if (!override_unsafe_setting && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None))
{
if (Pointer != 0)
{
sb.Append("IntPtr");
}
else
{
sb.Append(base.ToString());
if (Array > 0)
{
sb.Append("[");
for (int i = 1; i < Array; i++)
sb.Append(",");
sb.Append("]");
}
}
}
else
{
sb.Append(base.ToString());
for (int i = 0; i < Pointer; i++)
sb.Append("*");
if (Array > 0)
{
sb.Append("[");
for (int i = 1; i < Array; i++)
sb.Append(",");
sb.Append("]");
}
}
if (!String.IsNullOrEmpty(Name))
{
sb.Append(" ");
sb.Append(Name);
}
rebuild = false;
cache = sb.ToString();
return cache;
}
}
#endregion
#region Translate()
override public void Translate(EnumProcessor enum_processor, XPathNavigator overrides, string category, EnumCollection enums)
{
base.Translate(enum_processor, overrides, category, enums);
if (Pointer >= 3)
{
System.Diagnostics.Trace.WriteLine(String.Format(
"[Error] Type '{0}' has a high pointer level. Bindings will be incorrect.",
CurrentType));
}
// Find out the necessary wrapper types.
if (Pointer != 0)/* || CurrentType == "IntPtr")*/
{
if (CurrentType.ToLower().Contains("string") ||
CurrentType.ToLower().Contains("char") && Pointer > 1)
{
// string* -> [In] String[] or [Out] StringBuilder[]
QualifiedType =
Flow == FlowDirection.Out ?
"StringBuilder[]" :
"String[]";
Pointer = 0;
WrapperType = WrapperTypes.None;
}
else if (CurrentType.ToLower().Contains("char"))
{
// char* -> [In] String or [Out] StringBuilder
QualifiedType =
Flow == FlowDirection.Out ?
"StringBuilder" :
"String";
Pointer = 0;
WrapperType = WrapperTypes.None;
}
else if (CurrentType.ToLower().Contains("void") ||
(!String.IsNullOrEmpty(PreviousType) && PreviousType.ToLower().Contains("void"))) /*|| CurrentType.Contains("IntPtr"))*/
{
CurrentType = "IntPtr";
Pointer = 0;
WrapperType = WrapperTypes.GenericParameter;
}
else
{
WrapperType = WrapperTypes.ArrayParameter;
}
}
if (Reference)
WrapperType |= WrapperTypes.ReferenceParameter;
if (Utilities.Keywords.Contains(Name))
Name = Settings.KeywordEscapeCharacter + Name;
// This causes problems with bool arrays
//if (CurrentType.ToLower().Contains("bool"))
// WrapperType = WrapperTypes.BoolParameter;
}
#endregion
#region Static Members #region Static Members
// Returns the FlowDirection that matches the specified string // Returns the FlowDirection that matches the specified string
@ -387,26 +214,49 @@ namespace Bind.Structures
} }
#endregion #endregion
#region ToString
public override string ToString()
{
return String.Format("{2}{0} {1}",
base.ToString(),
Name,
Reference ?
Flow == FlowDirection.Out ? "out " : "ref " :
String.Empty);
}
#endregion
#region IEquatable<Parameter> Members
public bool Equals(Parameter other)
{
bool result =
base.Equals(other as Type) &&
Name.Equals(other.Name);
return result;
}
#endregion
} }
/// <summary> /// <summary>
/// Holds the parameter list of an opengl function. /// Holds the parameter list of an opengl function.
/// </summary> /// </summary>
class ParameterCollection : List<Parameter>, IComparable<ParameterCollection> class ParameterCollection : IList<Parameter>, IComparable<ParameterCollection>, IEquatable<ParameterCollection>
{ {
string cache = String.Empty; readonly List<Parameter> Parameters = new List<Parameter>();
string callStringCache = String.Empty;
private bool rebuild = true;
bool hasPointerParameters; bool hasPointerParameters;
bool hasReferenceParameters; bool hasReferenceParameters;
bool hasUnsignedParameters; bool hasUnsignedParameters;
bool hasGenericParameters; bool hasGenericParameters;
bool unsafe_types_allowed;
public bool Rebuild public bool Rebuild { get; set; }
{ Settings Settings { get; set; }
private get { return rebuild; }
set { rebuild = true;/*value;*/ }
}
#region Constructors #region Constructors
@ -430,13 +280,11 @@ namespace Bind.Structures
#endregion #endregion
#region void BuildCache() #region BuildCache
void BuildCache() void BuildCache()
{ {
BuildReferenceAndPointerParametersCache(); BuildReferenceAndPointerParametersCache();
BuildCallStringCache();
BuildToStringCache(unsafe_types_allowed);
Rebuild = false; Rebuild = false;
} }
@ -449,7 +297,9 @@ namespace Bind.Structures
get get
{ {
if (Rebuild) if (Rebuild)
{
BuildCache(); BuildCache();
}
return hasPointerParameters; return hasPointerParameters;
} }
@ -464,8 +314,10 @@ namespace Bind.Structures
get get
{ {
if (Rebuild) if (Rebuild)
{
BuildCache(); BuildCache();
}
return hasReferenceParameters; return hasReferenceParameters;
} }
} }
@ -479,7 +331,9 @@ namespace Bind.Structures
get get
{ {
if (Rebuild) if (Rebuild)
{
BuildCache(); BuildCache();
}
return hasUnsignedParameters; return hasUnsignedParameters;
} }
@ -494,7 +348,9 @@ namespace Bind.Structures
get get
{ {
if (Rebuild) if (Rebuild)
{
BuildCache(); BuildCache();
}
return hasGenericParameters; return hasGenericParameters;
} }
@ -524,61 +380,18 @@ namespace Bind.Structures
#endregion #endregion
#region new public void Add(Parameter p) #region ToString
new public void Add(Parameter p)
{
Rebuild = true;
base.Add(p);
}
#endregion
// Only use for debugging, not for code generation!
public override string ToString() public override string ToString()
{ {
return ToString(false);
}
#region public string ToString(bool override_unsafe_setting)
/// <summary>
/// Gets the parameter declaration string.
/// </summary>
/// <param name="override_unsafe_setting">
/// If true, unsafe types will be used even if the Settings.Compatibility.NoPublicUnsafeFunctions flag is set.
/// </param>
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
public string ToString(bool override_unsafe_setting)
{
Rebuild |= unsafe_types_allowed != override_unsafe_setting;
unsafe_types_allowed = override_unsafe_setting;
if (!Rebuild)
{
return cache;
}
else
{
BuildCache();
return cache;
}
}
#endregion
#region void BuildToStringCache(bool override_unsafe_setting)
void BuildToStringCache(bool override_unsafe_setting)
{
unsafe_types_allowed = override_unsafe_setting;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append("("); sb.Append("(");
if (Count > 0) if (Count > 0)
{ {
foreach (Parameter p in this) foreach (Parameter p in this)
{ {
sb.Append(p.ToString(override_unsafe_setting)); sb.Append(p.ToString());
sb.Append(", "); sb.Append(", ");
} }
sb.Replace(", ", ")", sb.Length - 2, 2); sb.Replace(", ", ")", sb.Length - 2, 2);
@ -586,91 +399,12 @@ namespace Bind.Structures
else else
sb.Append(")"); sb.Append(")");
cache = sb.ToString(); return sb.ToString();
} }
#endregion #endregion
#region public string CallString() #region ContainsType
public string CallString()
{
if (!Rebuild)
{
return callStringCache;
}
else
{
BuildCache();
return callStringCache;
}
}
#endregion
#region private void BuildCallStringCache()
/// <summary>
/// Builds a call string instance and caches it.
/// </summary>
private void BuildCallStringCache()
{
StringBuilder sb = new StringBuilder();
sb.Append("(");
if (Count > 0)
{
foreach (Parameter p in this)
{
if (p.Unchecked)
sb.Append("unchecked((" + p.QualifiedType + ")");
if (!p.Generic && p.CurrentType != "object")
{
if (p.CurrentType.ToLower().Contains("string"))
{
sb.Append(String.Format("({0}{1})",
p.QualifiedType, (p.Array > 0) ? "[]" : ""));
}
else if (p.IndirectionLevel != 0)
{
if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) &&
p.Pointer != 0 && p.CurrentType.Contains("void"))
sb.Append("(IntPtr)");
else
{
sb.Append("(");
sb.Append(p.QualifiedType);
for (int i = 0; i < p.IndirectionLevel; i++)
sb.Append("*");
sb.Append(")");
}
}
else
{
sb.Append(String.Format("({0})", p.QualifiedType));
}
}
sb.Append(p.Name);
if (p.Unchecked)
sb.Append(")");
sb.Append(", ");
}
sb.Replace(", ", ")", sb.Length - 2, 2);
}
else
{
sb.Append(")");
}
callStringCache = sb.ToString();
}
#endregion
public bool ContainsType(string type) public bool ContainsType(string type)
{ {
@ -680,6 +414,93 @@ namespace Bind.Structures
return false; return false;
} }
#endregion
#region IList<Parameter> Members
public void Add(Parameter p)
{
Parameters.Add(p);
Rebuild = true;
}
public void Clear()
{
Parameters.Clear();
Rebuild = true;
}
public bool Contains(Parameter item)
{
return Parameters.Contains(item);
}
public void CopyTo(Parameter[] array, int arrayIndex)
{
Parameters.CopyTo(array, arrayIndex);
}
public int Count
{
get { return Parameters.Count; }
}
public bool IsReadOnly
{
get { return (Parameters as ICollection<Parameter>).IsReadOnly; }
}
public bool Remove(Parameter item)
{
var result = Parameters.Remove(item);
if (result)
{
Rebuild = true;
}
return result;
}
public IEnumerator<Parameter> GetEnumerator()
{
return Parameters.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return Parameters.GetEnumerator();
}
public int IndexOf(Parameter item)
{
return Parameters.IndexOf(item);
}
public void Insert(int index, Parameter item)
{
Parameters.Insert(index, item);
Rebuild = true;
}
public void RemoveAt(int index)
{
Parameters.RemoveAt(index);
Rebuild = true;
}
public Parameter this[int index]
{
get
{
return Parameters[index];
}
set
{
Parameters[index] = value;
}
}
#endregion
#region IComparable<ParameterCollection> Members #region IComparable<ParameterCollection> Members
public int CompareTo(ParameterCollection other) public int CompareTo(ParameterCollection other)
@ -705,5 +526,22 @@ namespace Bind.Structures
} }
#endregion #endregion
#region IEquatable<ParameterCollection> Members
public bool Equals(ParameterCollection other)
{
if (Count != other.Count)
return false;
bool result = true;
for (int i = 0; i < Count && result; i++)
{
result &= this[i].Equals(other[i]);
}
return result;
}
#endregion
} }
} }