mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-27 00:25:40 +00:00
639 lines
18 KiB
C#
639 lines
18 KiB
C#
#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
|
|
{
|
|
/// <summary>
|
|
/// Represents a single parameter of an opengl function.
|
|
/// </summary>
|
|
public class Parameter : Type
|
|
{
|
|
string cache;
|
|
bool rebuild;
|
|
|
|
#region Constructors
|
|
|
|
/// <summary>
|
|
/// Creates a new Parameter without type and name.
|
|
/// </summary>
|
|
public Parameter()
|
|
:base()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new parameter from the parameters passed (deep copy).
|
|
/// </summary>
|
|
/// <param name="p">The parameter to copy from.</param>
|
|
public Parameter(Parameter p)
|
|
: base(p)
|
|
{
|
|
if (p == null)
|
|
return;
|
|
|
|
this.Name = p.Name;
|
|
this.Unchecked = p.Unchecked;
|
|
this.UnmanagedType = p.UnmanagedType;
|
|
this.Flow = p.Flow;
|
|
this.cache = p.cache;
|
|
//this.rebuild = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public string Name
|
|
|
|
string _name = String.Empty;
|
|
/// <summary>
|
|
/// Gets or sets the name of the parameter.
|
|
/// </summary>
|
|
public string Name
|
|
{
|
|
get { return _name; }
|
|
set
|
|
{
|
|
if (_name != value)
|
|
{
|
|
_name = value;
|
|
rebuild = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region UnmanagedType property
|
|
|
|
UnmanagedType _unmanaged_type;
|
|
/// <summary>
|
|
/// Gets or sets the name of the parameter.
|
|
/// </summary>
|
|
private UnmanagedType UnmanagedType
|
|
{
|
|
get { return _unmanaged_type; }
|
|
set
|
|
{
|
|
if (_unmanaged_type != value)
|
|
{
|
|
_unmanaged_type = value;
|
|
rebuild = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public FlowDirection Flow
|
|
|
|
/// <summary>
|
|
/// Enumarates the possible flows of a parameter (ie. is this parameter
|
|
/// used as input or as output?)
|
|
/// </summary>
|
|
public enum FlowDirection
|
|
{
|
|
Undefined = 0,
|
|
In,
|
|
Out
|
|
}
|
|
|
|
FlowDirection _flow;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the flow of the parameter.
|
|
/// </summary>
|
|
public FlowDirection Flow
|
|
{
|
|
get { return _flow; }
|
|
set
|
|
{
|
|
if (_flow != value)
|
|
{
|
|
_flow = value;
|
|
rebuild = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
#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;
|
|
rebuild = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public override string CurrentType
|
|
|
|
public override string CurrentType
|
|
{
|
|
get
|
|
{
|
|
return base.CurrentType;
|
|
}
|
|
set
|
|
{
|
|
base.CurrentType = value;
|
|
rebuild = true;
|
|
}
|
|
}
|
|
|
|
#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)
|
|
{
|
|
if (!String.IsNullOrEmpty(cache) && !rebuild)
|
|
{
|
|
return cache;
|
|
}
|
|
else
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
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);
|
|
}
|
|
|
|
rebuild = false;
|
|
cache = sb.ToString();
|
|
return cache;
|
|
}
|
|
}
|
|
|
|
#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);
|
|
|
|
// Try to find out if it is an enum. If the type exists in the normal GLEnums list, use this.
|
|
// Otherwise, try to find it in the aux enums list. If it exists in neither, it is not an enum.
|
|
bool normal = false;
|
|
bool aux = false;
|
|
normal = Enum.GLEnums.TryGetValue(p.CurrentType, out @enum);
|
|
if (!normal)
|
|
aux = Enum.AuxEnums != null && Enum.AuxEnums.TryGetValue(p.CurrentType, out @enum);
|
|
|
|
// Translate enum types
|
|
if ((normal || aux) && @enum.Name != "GLenum")
|
|
{
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
{
|
|
p.CurrentType = "int";
|
|
}
|
|
else
|
|
{
|
|
if (normal)
|
|
{
|
|
p.CurrentType = p.CurrentType.Insert(0, String.Format("{0}.", Settings.NormalEnumsClass));
|
|
}
|
|
else if (aux)
|
|
{
|
|
p.CurrentType = p.CurrentType.Insert(0, String.Format("{0}.", Settings.AuxEnumsClass));
|
|
}
|
|
}
|
|
}
|
|
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.NormalEnumsClass, Category);
|
|
}
|
|
else
|
|
{
|
|
p.CurrentType = String.Format("{0}.{1}", Settings.NormalEnumsClass, Settings.CompleteEnumName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p.CurrentType = "int";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This is not enum, default translation:
|
|
if (p.CurrentType == "PIXELFORMATDESCRIPTOR" || p.CurrentType == "LAYERPLANEDESCRIPTOR" ||
|
|
p.CurrentType == "GLYPHMETRICSFLOAT")
|
|
{
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
{
|
|
p.CurrentType = p.CurrentType.Insert(0, "Gdi.");
|
|
}
|
|
else
|
|
{
|
|
if (p.CurrentType == "PIXELFORMATDESCRIPTOR")
|
|
p.CurrentType ="PixelFormatDescriptor";
|
|
else if (p.CurrentType == "LAYERPLANEDESCRIPTOR")
|
|
p.CurrentType = "LayerPlaneDescriptor";
|
|
else if (p.CurrentType == "GLYPHMETRICSFLOAT")
|
|
p.CurrentType = "GlyphMetricsFloat";
|
|
}
|
|
}
|
|
else if (p.CurrentType == "XVisualInfo")
|
|
{
|
|
//p.Pointer = false;
|
|
//p.Reference = true;
|
|
|
|
}
|
|
else
|
|
{
|
|
p.CurrentType = s;
|
|
}
|
|
p.CurrentType =
|
|
Bind.Structures.Type.CSTypes.ContainsKey(p.CurrentType) ?
|
|
Bind.Structures.Type.CSTypes[p.CurrentType] : p.CurrentType;
|
|
|
|
if (p.CurrentType == "IntPtr")
|
|
{
|
|
p.Pointer = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//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.Reference)
|
|
{
|
|
p.WrapperType = WrapperTypes.ReferenceParameter;
|
|
}
|
|
|
|
if (p.CurrentType.ToLower().Contains("bool"))
|
|
{
|
|
// Is this actually used anywhere?
|
|
p.WrapperType = WrapperTypes.BoolParameter;
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holds the parameter list of an opengl function.
|
|
/// </summary>
|
|
public class ParameterCollection : List<Parameter>
|
|
{
|
|
string cache = String.Empty;
|
|
string callStringCache = String.Empty;
|
|
private bool rebuild = true;
|
|
bool hasPointerParameters;
|
|
bool hasReferenceParameters;
|
|
private bool Rebuild
|
|
{
|
|
get { return rebuild; }
|
|
set
|
|
{
|
|
rebuild = value;
|
|
}
|
|
}
|
|
|
|
#region Constructors
|
|
|
|
public ParameterCollection()
|
|
{
|
|
}
|
|
|
|
public ParameterCollection(ParameterCollection pc)
|
|
{
|
|
foreach (Parameter p in pc)
|
|
{
|
|
this.Add(new Parameter(p));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
void BuildCache()
|
|
{
|
|
BuildCallStringCache();
|
|
BuildToStringCache();
|
|
BuildReferenceAndPointerParametersCache();
|
|
Rebuild = false;
|
|
}
|
|
|
|
public bool HasPointerParameters
|
|
{
|
|
get
|
|
{
|
|
if (!rebuild)
|
|
{
|
|
return hasPointerParameters;
|
|
}
|
|
else
|
|
{
|
|
BuildCache();
|
|
return hasPointerParameters;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool HasReferenceParameters
|
|
{
|
|
get
|
|
{
|
|
if (!Rebuild)
|
|
{
|
|
return hasReferenceParameters;
|
|
}
|
|
else
|
|
{
|
|
BuildCache();
|
|
return hasReferenceParameters;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BuildReferenceAndPointerParametersCache()
|
|
{
|
|
foreach (Parameter p in this)
|
|
{
|
|
if (p.Pointer)
|
|
hasPointerParameters = true;
|
|
|
|
if (p.Reference)
|
|
hasReferenceParameters = true;
|
|
}
|
|
}
|
|
|
|
#region new public void Add(Parameter p)
|
|
|
|
new public void Add(Parameter p)
|
|
{
|
|
Rebuild = true;
|
|
base.Add(p);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region override public string ToString()
|
|
|
|
/// <summary>
|
|
/// Gets the parameter declaration string.
|
|
/// </summary>
|
|
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
|
|
override public string ToString()
|
|
{
|
|
return ToString(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public string ToString(bool taoCompatible)
|
|
|
|
/// <summary>
|
|
/// Gets the parameter declaration string.
|
|
/// </summary>
|
|
/// <param name="getCLSCompliant">If true, all types will be replaced by their CLSCompliant C# equivalents</param>
|
|
/// <param name="CSTypes">The list of C# types equivalent to the OpenGL types.</param>
|
|
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
|
|
public string ToString(bool taoCompatible)
|
|
{
|
|
if (!Rebuild)
|
|
{
|
|
return cache;
|
|
}
|
|
else
|
|
{
|
|
BuildCache();
|
|
return cache;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region void BuildToStringCache()
|
|
|
|
void BuildToStringCache()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append("(");
|
|
if (this.Count > 0)
|
|
{
|
|
foreach (Parameter p in this)
|
|
{
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
{
|
|
sb.Append(p.ToString(true));
|
|
}
|
|
else
|
|
{
|
|
sb.Append(p.ToString());
|
|
}
|
|
sb.Append(", ");
|
|
}
|
|
sb.Replace(", ", ")", sb.Length - 2, 2);
|
|
}
|
|
else
|
|
sb.Append(")");
|
|
|
|
cache = sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public string CallString()
|
|
|
|
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 (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 if (p.Pointer || p.Array > 0 || p.Reference)
|
|
{
|
|
sb.Append(String.Format("({0}*)",
|
|
p.CurrentType /*, (p.Pointer || p.Array > 0) ? "*" : ""*/));
|
|
}
|
|
//else if (p.Reference)
|
|
//{
|
|
// sb.Append(String.Format("{0} ({1})",
|
|
// p.Flow == Parameter.FlowDirection.Out ? "out" : "ref", p.CurrentType));
|
|
//}
|
|
else
|
|
{
|
|
sb.Append(String.Format("({0})", p.CurrentType));
|
|
}
|
|
}
|
|
|
|
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(")");
|
|
}
|
|
|
|
callStringCache = sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
public bool ContainsType(string type)
|
|
{
|
|
foreach (Parameter p in this)
|
|
if (p.CurrentType == type)
|
|
return true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|