#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info */ #endregion using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Xml.XPath; namespace Bind.Structures { /// /// Represents a single parameter of an opengl function. /// class Parameter : Type, IComparable, IEquatable { string cache; #region Constructors /// /// Creates a new Parameter without type and name. /// public Parameter() :base() { } /// /// Creates a new parameter from the parameters passed (deep copy). /// /// The parameter to copy from. public Parameter(Parameter p) : base(p) { if (p == null) return; Name = p.Name; Unchecked = p.Unchecked; UnmanagedType = p.UnmanagedType; Generic = p.Generic; Flow = p.Flow; cache = p.cache; //this.rebuild = false; } #endregion #region RawName /// /// Gets or sets the raw name of the parameter. /// public string RawName { get; private set; } #endregion #region Name /// /// Gets the name of the parameter. If the name matches a keyword of the current language, /// then it is escaped with . /// public string Name { get { return RawName; } set { if (RawName != value) { while (value.StartsWith("*")) { Pointer++; value = value.Substring(1); } RawName = value; } } } #endregion #region UnmanagedType UnmanagedType _unmanaged_type; /// /// Gets or sets the name of the parameter. /// private UnmanagedType UnmanagedType { get { return _unmanaged_type; } set { if (_unmanaged_type != value) { _unmanaged_type = value; } } } #endregion #region public FlowDirection Flow FlowDirection _flow; /// /// Gets or sets the flow of the parameter. /// public FlowDirection Flow { get { return _flow; } set { if (_flow != value) { _flow = value; } } } #endregion #region public bool NeedsPin public bool NeedsPin { get { return (Array > 0 || Reference || CurrentType == "object") && !CurrentType.ToLower().Contains("string"); } } #endregion #region public bool Unchecked private bool _unchecked; public bool Unchecked { get { return _unchecked; } set { if (_unchecked != value) { _unchecked = value; } } } #endregion #region public bool Generic bool generic; public bool Generic { get { return generic; } set { generic = value; } } #endregion #region public bool DiffersOnlyOnReference // Returns true if this parameter differs only on reference compared to another parameter, i.e: // returns true for 'int' & 'ref int' // returns true for 'ref float' & 'float' // returns false 'int' & 'int*' // returns false 'int' & 'int[]' // returns false 'int' & 'float' public bool DiffersOnlyOnReference(Parameter other) { return CurrentType == other.CurrentType && (Reference && !(other.Reference || other.Array > 0 || other.Pointer != 0) || other.Reference && !(Reference || Array > 0 || Pointer != 0)); } #endregion #region public string ComputeSize string computeSize; public string ComputeSize { get { return computeSize; } set { computeSize = value; } } #endregion #region Static Members // Returns the FlowDirection that matches the specified string // ("out" or "in", otherwise undefined). public static FlowDirection GetFlowDirection(string direction) { return direction == "out" ? FlowDirection.Out : direction == "in" ? FlowDirection.In : FlowDirection.Undefined; } #endregion #region IComparable Members public int CompareTo(Parameter other) { int result = base.CompareTo(other); if (result == 0) result = Name.CompareTo(other.Name); return result; } #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 Members public bool Equals(Parameter other) { bool result = base.Equals(other as Type) && Name.Equals(other.Name); return result; } #endregion } /// /// Holds the parameter list of an opengl function. /// class ParameterCollection : IList, IComparable, IEquatable { readonly List Parameters = new List(); bool hasPointerParameters; bool hasReferenceParameters; bool hasUnsignedParameters; bool hasGenericParameters; public bool Rebuild { get; set; } Settings Settings { get; set; } #region Constructors public ParameterCollection() { } public ParameterCollection(ParameterCollection pc) { foreach (Parameter p in pc) { Add(new Parameter(p)); } } public ParameterCollection(IEnumerable parameters) { foreach (Parameter p in parameters) Add(new Parameter(p)); } #endregion #region BuildCache void BuildCache() { BuildReferenceAndPointerParametersCache(); Rebuild = false; } #endregion #region public bool HasPointerParameters public bool HasPointerParameters { get { if (Rebuild) { BuildCache(); } return hasPointerParameters; } } #endregion #region public bool HasReferenceParameters public bool HasReferenceParameters { get { if (Rebuild) { BuildCache(); } return hasReferenceParameters; } } #endregion #region public bool HasUnsignedParameters public bool HasUnsignedParameters { get { if (Rebuild) { BuildCache(); } return hasUnsignedParameters; } } #endregion #region public bool HasGenericParameters public bool HasGenericParameters { get { if (Rebuild) { BuildCache(); } return hasGenericParameters; } } #endregion #region void BuildReferenceAndPointerParametersCache() void BuildReferenceAndPointerParametersCache() { foreach (Parameter p in this) { if (p.Pointer != 0 || p.CurrentType.Contains("IntPtr")) hasPointerParameters = true; if (p.Reference) hasReferenceParameters = true; if (p.Unsigned) hasUnsignedParameters = true; if (p.Generic) hasGenericParameters = true; } } #endregion #region ToString // Only use for debugging, not for code generation! public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("("); if (Count > 0) { foreach (Parameter p in this) { sb.Append(p.ToString()); sb.Append(", "); } sb.Replace(", ", ")", sb.Length - 2, 2); } else sb.Append(")"); return sb.ToString(); } #endregion #region ContainsType public bool ContainsType(string type) { foreach (Parameter p in this) if (p.CurrentType == type) return true; return false; } #endregion #region IList 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).IsReadOnly; } } public bool Remove(Parameter item) { var result = Parameters.Remove(item); if (result) { Rebuild = true; } return result; } public IEnumerator 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 Members public int CompareTo(ParameterCollection other) { if (Count < other.Count) { return -1; } else if (Count > other.Count) { return 1; } else { for (int i = 0; i < Count; i++) { int result = this[i].CompareTo(other[i]); if (result != 0) return result; } return 0; } } #endregion #region IEquatable 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 } }