#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace Bind.Structures { #region Parameter class /// /// Represents a single parameter of an opengl function. /// public class Parameter : Type { #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; this.Name = !String.IsNullOrEmpty(p.Name) ? new string(p.Name.ToCharArray()) : ""; this.Unchecked = p.Unchecked; this.UnmanagedType = p.UnmanagedType; this.Flow = p.Flow; } #endregion #region public string Name string _name; /// /// Gets or sets the name of the parameter. /// public string Name { get { return _name; } set { _name = value; } } #endregion #region UnmanagedType property UnmanagedType _unmanaged_type; /// /// Gets or sets the name of the parameter. /// private UnmanagedType UnmanagedType { get { return _unmanaged_type; } set { _unmanaged_type = value; } } #endregion #region public FlowDirection Flow /// /// Enumarates the possible flows of a parameter (ie. is this parameter /// used as input or as output?) /// public enum FlowDirection { Undefined = 0, In, Out } FlowDirection _flow; /// /// Gets or sets the flow of the parameter. /// public FlowDirection Flow { get { return _flow; } set { _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 { _unchecked = value; } } #endregion #region override public string ToString() override public string ToString() { return ToString(false); } #endregion #region public string ToString(bool taoCompatible) public string ToString(bool taoCompatible) { StringBuilder sb = new StringBuilder(); //if (UnmanagedType == UnmanagedType.AsAny && Flow == FlowDirection.In) // sb.Append("[MarshalAs(UnmanagedType.AsAny)] "); //if (UnmanagedType == UnmanagedType.LPArray) // sb.Append("[MarshalAs(UnmanagedType.LPArray)] "); //if (Flow == FlowDirection.Out && !Array && !(Type == "IntPtr")) // sb.Append("out "); if (Flow == FlowDirection.Out) sb.Append("[Out] "); else if (Flow == FlowDirection.Undefined) sb.Append("[In, Out] "); if (Reference) { if (Flow == FlowDirection.Out) sb.Append("out "); else sb.Append("ref "); } if (taoCompatible && Settings.Compatibility == Settings.Legacy.Tao) { if (Pointer) { sb.Append("IntPtr"); } else { sb.Append(CurrentType); if (Array > 0) sb.Append("[]"); } } else { sb.Append(CurrentType); if (Pointer) sb.Append("*"); if (Array > 0) sb.Append("[]"); } if (!String.IsNullOrEmpty(Name)) { sb.Append(" "); sb.Append(Utilities.Keywords.Contains(Name) ? "@" + Name : Name); } return sb.ToString(); } #endregion #region internal static Parameter Translate(Parameter par, string Category) internal static Parameter Translate(Parameter par, string Category) { Enum @enum; string s; Parameter p = new Parameter(par); // Translate enum types if (Enum.GLEnums.TryGetValue(p.CurrentType, out @enum) && @enum.Name != "GLenum") { if (Settings.Compatibility == Settings.Legacy.Tao) p.CurrentType = "int"; else p.CurrentType = p.CurrentType.Insert(0, String.Format("{0}.", Settings.GLEnumsClass)); } else if (Bind.Structures.Type.GLTypes.TryGetValue(p.CurrentType, out s)) { // Check if the parameter is a generic GLenum. If yes, // check if a better match exists: if (s.Contains("GLenum") && !String.IsNullOrEmpty(Category)) { if (Settings.Compatibility == Settings.Legacy.None) { // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc) if (Enum.GLEnums.ContainsKey(Category)) { p.CurrentType = String.Format("{0}.{1}", Settings.GLEnumsClass, Category); } else { p.CurrentType = String.Format("{0}.{1}", Settings.GLEnumsClass, Settings.CompleteEnumName); } } else { p.CurrentType = "int"; } } else { // This is not enum, default translation: p.CurrentType = s; p.CurrentType = Bind.Structures.Type.CSTypes.ContainsKey(p.CurrentType) ? Bind.Structures.Type.CSTypes[p.CurrentType] : p.CurrentType; } } //if (CSTypes.ContainsKey(p.CurrentType)) // p.CurrentType = CSTypes[p.CurrentType]; // Translate pointer parameters if (p.Pointer) { p.WrapperType = WrapperTypes.ArrayParameter; if (p.CurrentType.ToLower().Contains("char") || p.CurrentType.ToLower().Contains("string")) { // char* or string -> [In] String or [Out] StringBuilder p.CurrentType = p.Flow == Parameter.FlowDirection.Out ? "System.Text.StringBuilder" : "System.String"; p.Pointer = false; p.WrapperType = WrapperTypes.None; } else if (p.CurrentType.ToLower().Contains("void")) { p.WrapperType = WrapperTypes.GenericParameter; } } if (p.CurrentType.ToLower().Contains("bool")) { // Is this actually used anywhere? p.WrapperType = WrapperTypes.BoolParameter; } return p; } #endregion } #endregion #region ParameterCollection class /// /// Holds the parameter list of an opengl function. /// public class ParameterCollection : List { #region Constructors public ParameterCollection() { } public ParameterCollection(ParameterCollection pc) { foreach (Parameter p in pc) { this.Add(new Parameter(p)); } } #endregion #region override public string ToString() /// /// Gets the parameter declaration string. /// /// The parameter list of an opengl function in the form ( [parameters] ) override public string ToString() { return ToString(false); } #endregion #region public string ToString(bool taoCompatible) /// /// Gets the parameter declaration string. /// /// If true, all types will be replaced by their CLSCompliant C# equivalents /// The list of C# types equivalent to the OpenGL types. /// The parameter list of an opengl function in the form ( [parameters] ) public string ToString(bool taoCompatible) { StringBuilder sb = new StringBuilder(); sb.Append("("); if (this.Count > 0) { foreach (Parameter p in this) { if (taoCompatible) { sb.Append(p.ToString(true)); } else { sb.Append(p.ToString()); } sb.Append(", "); } sb.Replace(", ", ")", sb.Length - 2, 2); } else sb.Append(")"); return sb.ToString(); } #endregion public string CallString() { return CallString(false); } public string CallString(bool taoCompatible) { StringBuilder sb = new StringBuilder(); sb.Append("("); if (this.Count > 0) { foreach (Parameter p in this) { if (p.Unchecked) sb.Append("unchecked((" + p.CurrentType + ")"); if (p.CurrentType != "object") { if (p.CurrentType.ToLower().Contains("string")) { sb.Append(String.Format( "({0}{1})", p.CurrentType, (p.Array > 0) ? "[]" : "")); } else { sb.Append(String.Format( "({0}{1})", p.CurrentType, (p.Pointer || p.Array > 0 || p.Reference) ? "*" : "")); } } sb.Append( Utilities.Keywords.Contains(p.Name) ? "@" + p.Name : p.Name ); if (p.Unchecked) sb.Append(")"); sb.Append(", "); } sb.Replace(", ", ")", sb.Length - 2, 2); } else { sb.Append(")"); } return sb.ToString(); } public bool ContainsType(string type) { foreach (Parameter p in this) if (p.CurrentType == type) return true; return false; } } #endregion }