mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-04-17 16:31:55 +00:00
Moved enum, constant, delegate and function transformations to EnumProcessor and FuncProcessor respectively.
Removed global enum, delegate and function collections. Simplified loading process and removed global Initialize() methods. Read "count" attributes for function parameters in overrides.xml. Disabled wgl/glx/glu generators. Removed large amounts of stale code.
This commit is contained in:
parent
31b80891e2
commit
137818d10c
|
@ -83,6 +83,8 @@ namespace Bind.ES
|
|||
p.Name = param.GetAttribute("name", String.Empty);
|
||||
|
||||
string element_count = param.GetAttribute("elementcount", String.Empty);
|
||||
if (String.IsNullOrEmpty(element_count))
|
||||
element_count = param.GetAttribute("count", String.Empty);
|
||||
if (!String.IsNullOrEmpty(element_count))
|
||||
p.ElementCount = Int32.Parse(element_count);
|
||||
|
||||
|
@ -92,7 +94,7 @@ namespace Bind.ES
|
|||
break;
|
||||
}
|
||||
}
|
||||
d.Translate(overrides);
|
||||
//d.Translate(overrides);
|
||||
delegates.Add(d);
|
||||
}
|
||||
}
|
||||
|
@ -188,9 +190,7 @@ namespace Bind.ES
|
|||
}
|
||||
|
||||
Utilities.Merge(enums, all);
|
||||
return new EnumProcessor(overrides).Process(enums);
|
||||
//enums.Translate(overrides);
|
||||
//return enums;
|
||||
return enums;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,14 +28,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.XPath;
|
||||
using Bind.Structures;
|
||||
using Delegate = Bind.Structures.Delegate;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
class FuncProcessor
|
||||
{
|
||||
const string Path = "/overrides/replace/function[@name='{0}']";
|
||||
{
|
||||
const string Path = "/overrides/replace/function[@name='{0}' and @extension='{1}']";
|
||||
static readonly Regex Endings =
|
||||
new Regex(@"((((d|f|fi)|u?[isb])_?v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
||||
static readonly Regex EndingsNotToTrim =
|
||||
new Regex("(ib|[tdrey]s|[eE]n[vd]|bled|Flag|Tess|Status|Pixels|Instanced|Indexed|Varyings|Boolean|IDs)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
||||
static readonly Regex EndingsAddV = new Regex("^0", RegexOptions.Compiled);
|
||||
|
||||
XPathDocument Overrides { get; set; }
|
||||
|
||||
public FuncProcessor(XPathDocument overrides)
|
||||
|
@ -45,5 +53,629 @@ namespace Bind
|
|||
|
||||
Overrides = overrides;
|
||||
}
|
||||
|
||||
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums)
|
||||
{
|
||||
Console.WriteLine("Processing delegates.");
|
||||
var nav = Overrides.CreateNavigator();
|
||||
foreach (var d in delegates.Values)
|
||||
{
|
||||
TranslateReturnType(nav, d, enums);
|
||||
TranslateParameters(nav, d, enums);
|
||||
}
|
||||
|
||||
Console.WriteLine("Generating wrappers.");
|
||||
var wrappers = CreateWrappers(delegates, enums);
|
||||
Console.WriteLine("Creating CLS compliant overloads.");
|
||||
wrappers = CreateCLSCompliantWrappers(wrappers, enums);
|
||||
Console.WriteLine("Removing non-CLS compliant duplicates.");
|
||||
return MarkCLSCompliance(wrappers);
|
||||
}
|
||||
|
||||
// Trims unecessary suffices from the specified OpenGL function name.
|
||||
static string TrimName(string name, bool keep_extension)
|
||||
{
|
||||
string trimmed_name = Utilities.StripGL2Extension(name);
|
||||
string extension = Utilities.GetGL2Extension(name);
|
||||
|
||||
// Note: some endings should not be trimmed, for example: 'b' from Attrib.
|
||||
// Check the endingsNotToTrim regex for details.
|
||||
Match m = EndingsNotToTrim.Match(trimmed_name);
|
||||
if ((m.Index + m.Length) != trimmed_name.Length)
|
||||
{
|
||||
m = Endings.Match(trimmed_name);
|
||||
|
||||
if (m.Length > 0 && m.Index + m.Length == trimmed_name.Length)
|
||||
{
|
||||
// Only trim endings, not internal matches.
|
||||
if (m.Value[m.Length - 1] == 'v' && EndingsAddV.IsMatch(name) &&
|
||||
!name.StartsWith("Get") && !name.StartsWith("MatrixIndex"))
|
||||
{
|
||||
// Only trim ending 'v' when there is a number
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index) + "v";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!trimmed_name.EndsWith("xedv"))
|
||||
{
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trimmed_name;
|
||||
}
|
||||
|
||||
// Translates the opengl return type to the equivalent C# type.
|
||||
//
|
||||
// First, we use the official typemap (gl.tm) to get the correct type.
|
||||
// Then we override this, when it is:
|
||||
// 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption)
|
||||
// 2) An array (translates to IntPtr)
|
||||
// 3) A generic object or void* (translates to IntPtr)
|
||||
// 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise).
|
||||
// Return types must always be CLS-compliant, because .Net does not support overloading on return types.
|
||||
static void TranslateReturnType(XPathNavigator nav, Delegate d, EnumCollection enums)
|
||||
{
|
||||
string name = TrimName(d.Name, false);
|
||||
string ext = d.Extension;
|
||||
|
||||
var function_override = nav.SelectSingleNode(String.Format(Path, name, ext));
|
||||
if (function_override != null)
|
||||
{
|
||||
XPathNavigator return_override = function_override.SelectSingleNode("returns");
|
||||
if (return_override != null)
|
||||
{
|
||||
d.ReturnType.CurrentType = return_override.Value;
|
||||
}
|
||||
}
|
||||
|
||||
d.ReturnType.Translate(nav, d.Category, enums);
|
||||
|
||||
if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0)
|
||||
{
|
||||
d.ReturnType.QualifiedType = "System.IntPtr";
|
||||
d.ReturnType.WrapperType = WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
{
|
||||
d.ReturnType.QualifiedType = "System.IntPtr";
|
||||
d.ReturnType.WrapperType = WrapperTypes.StringReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.CurrentType.ToLower() == "object")
|
||||
{
|
||||
d.ReturnType.QualifiedType = "System.IntPtr";
|
||||
d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.CurrentType.Contains("GLenum"))
|
||||
{
|
||||
if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None)
|
||||
d.ReturnType.QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, Settings.CompleteEnumName);
|
||||
else
|
||||
d.ReturnType.QualifiedType = "int";
|
||||
}
|
||||
|
||||
d.ReturnType.CurrentType = d.ReturnType.GetCLSCompliantType();
|
||||
}
|
||||
|
||||
static void TranslateParameters(XPathNavigator nav, Delegate d, EnumCollection enums)
|
||||
{
|
||||
string name = TrimName(d.Name, false);
|
||||
string ext = d.Extension;
|
||||
ext = String.IsNullOrEmpty(ext) ? "Core" : ext;
|
||||
|
||||
var function_override = nav.SelectSingleNode(String.Format(Path, name, ext));
|
||||
for (int i = 0; i < d.Parameters.Count; i++)
|
||||
{
|
||||
if (function_override != null)
|
||||
{
|
||||
XPathNavigator param_override = function_override.SelectSingleNode(
|
||||
String.Format("param[@name='{0}']", d.Parameters[i].Name));
|
||||
if (param_override != null)
|
||||
{
|
||||
foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element))
|
||||
{
|
||||
switch (node.Name)
|
||||
{
|
||||
case "type":
|
||||
d.Parameters[i].CurrentType = (string)node.TypedValue;
|
||||
break;
|
||||
case "name":
|
||||
d.Parameters[i].Name = (string)node.TypedValue;
|
||||
break;
|
||||
case "flow":
|
||||
d.Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.Parameters[i].Translate(nav, d.Category, enums);
|
||||
if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple"))
|
||||
d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
|
||||
}
|
||||
}
|
||||
|
||||
static FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums)
|
||||
{
|
||||
var wrappers = new FunctionCollection();
|
||||
foreach (var d in delegates.Values)
|
||||
{
|
||||
wrappers.AddRange(CreateNormalWrappers(d, enums));
|
||||
}
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
static FunctionCollection CreateCLSCompliantWrappers(FunctionCollection functions, EnumCollection enums)
|
||||
{
|
||||
// If the function is not CLS-compliant (e.g. it contains unsigned parameters)
|
||||
// we need to create a CLS-Compliant overload. However, we should only do this
|
||||
// iff the opengl function does not contain unsigned/signed overloads itself
|
||||
// to avoid redefinitions.
|
||||
var wrappers = new FunctionCollection();
|
||||
foreach (var list in functions.Values)
|
||||
{
|
||||
foreach (var f in list)
|
||||
{
|
||||
wrappers.AddChecked(f);
|
||||
|
||||
if (!f.CLSCompliant)
|
||||
{
|
||||
Function cls = new Function(f);
|
||||
|
||||
cls.Body.Clear();
|
||||
CreateBody(cls, true, enums);
|
||||
|
||||
bool modified = false;
|
||||
for (int i = 0; i < f.Parameters.Count; i++)
|
||||
{
|
||||
cls.Parameters[i].CurrentType = cls.Parameters[i].GetCLSCompliantType();
|
||||
if (cls.Parameters[i].CurrentType != f.Parameters[i].CurrentType)
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
wrappers.AddChecked(cls);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
static FunctionCollection MarkCLSCompliance(FunctionCollection collection)
|
||||
{
|
||||
//foreach (var w in
|
||||
// (from list in collection
|
||||
// from w1 in list.Value
|
||||
// from w2 in list.Value
|
||||
// where
|
||||
// w1.TrimmedName == w2.TrimmedName &&
|
||||
// w1.Parameters.Count == w2.Parameters.Count &&
|
||||
// ParametersDifferOnlyInReference(w1.Parameters, w2.Parameters)
|
||||
// select !w1.Parameters.HasReferenceParameters ? w1 : w2))
|
||||
// {
|
||||
// results.Add(w);
|
||||
// }
|
||||
|
||||
foreach (List<Function> wrappers in collection.Values)
|
||||
{
|
||||
restart:
|
||||
for (int i = 0; i < wrappers.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < wrappers.Count; j++)
|
||||
{
|
||||
if (wrappers[i].TrimmedName == wrappers[j].TrimmedName && wrappers[i].Parameters.Count == wrappers[j].Parameters.Count)
|
||||
{
|
||||
bool function_i_is_problematic = false;
|
||||
bool function_j_is_problematic = false;
|
||||
|
||||
int k;
|
||||
for (k = 0; k < wrappers[i].Parameters.Count; k++)
|
||||
{
|
||||
if (wrappers[i].Parameters[k].CurrentType != wrappers[j].Parameters[k].CurrentType)
|
||||
break;
|
||||
|
||||
if (wrappers[i].Parameters[k].DiffersOnlyOnReference(wrappers[j].Parameters[k]))
|
||||
if (wrappers[i].Parameters[k].Reference)
|
||||
function_i_is_problematic = true;
|
||||
else
|
||||
function_j_is_problematic = true;
|
||||
}
|
||||
|
||||
if (k == wrappers[i].Parameters.Count)
|
||||
{
|
||||
if (function_i_is_problematic)
|
||||
wrappers.RemoveAt(i);
|
||||
//wrappers[i].CLSCompliant = false;
|
||||
if (function_j_is_problematic)
|
||||
wrappers.RemoveAt(j);
|
||||
//wrappers[j].CLSCompliant = false;
|
||||
|
||||
if (function_i_is_problematic || function_j_is_problematic)
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
static IEnumerable<Function> CreateNormalWrappers(Delegate d, EnumCollection enums)
|
||||
{
|
||||
Function f = new Function(d);
|
||||
WrapReturnType(f);
|
||||
foreach (var wrapper in WrapParameters(f, enums))
|
||||
{
|
||||
yield return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Function> WrapParameters(Function func, EnumCollection enums)
|
||||
{
|
||||
Function f;
|
||||
|
||||
if (func.Parameters.HasPointerParameters)
|
||||
{
|
||||
Function _this = new Function(func);
|
||||
// Array overloads
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter && p.ElementCount != 1)
|
||||
{
|
||||
p.Reference = false;
|
||||
p.Array++;
|
||||
p.Pointer--;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
CreateBody(f, false, enums);
|
||||
yield return f;
|
||||
foreach (var w in WrapVoidPointers(new Function(f), enums))
|
||||
yield return w;
|
||||
|
||||
_this = new Function(func);
|
||||
// Reference overloads
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter)
|
||||
{
|
||||
p.Reference = true;
|
||||
p.Array--;
|
||||
p.Pointer--;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
CreateBody(f, false, enums);
|
||||
yield return f;
|
||||
foreach (var w in WrapVoidPointers(new Function(f), enums))
|
||||
yield return w;
|
||||
|
||||
_this = func;
|
||||
// Pointer overloads
|
||||
// Should be last to work around Intellisense bug, where
|
||||
// array overloads are not reported if there is a pointer overload.
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter)
|
||||
{
|
||||
p.Reference = false;
|
||||
//p.Array--;
|
||||
//p.Pointer++;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
CreateBody(f, false, enums);
|
||||
yield return f;
|
||||
foreach (var w in WrapVoidPointers(new Function(f), enums))
|
||||
yield return w;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = new Function(func);
|
||||
CreateBody(f, false, enums);
|
||||
yield return f;
|
||||
}
|
||||
}
|
||||
|
||||
static int index;
|
||||
static IEnumerable<Function> WrapVoidPointers(Function func, EnumCollection enums)
|
||||
{
|
||||
if (index >= 0 && index < func.Parameters.Count)
|
||||
{
|
||||
if (func.Parameters[index].WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
foreach (var w in WrapVoidPointers(func, enums))
|
||||
yield return w;
|
||||
--index;
|
||||
|
||||
// On stack rewind, create generic wrappers
|
||||
func.Parameters[index].Reference = true;
|
||||
func.Parameters[index].Array = 0;
|
||||
func.Parameters[index].Pointer = 0;
|
||||
func.Parameters[index].Generic = true;
|
||||
func.Parameters[index].CurrentType = "T" + index.ToString();
|
||||
func.Parameters[index].Flow = FlowDirection.Undefined;
|
||||
func.Parameters.Rebuild = true;
|
||||
CreateBody(func, false, enums);
|
||||
yield return new Function(func);
|
||||
|
||||
func.Parameters[index].Reference = false;
|
||||
func.Parameters[index].Array = 1;
|
||||
func.Parameters[index].Pointer = 0;
|
||||
func.Parameters[index].Generic = true;
|
||||
func.Parameters[index].CurrentType = "T" + index.ToString();
|
||||
func.Parameters[index].Flow = FlowDirection.Undefined;
|
||||
func.Parameters.Rebuild = true;
|
||||
CreateBody(func, false, enums);
|
||||
yield return new Function(func);
|
||||
|
||||
func.Parameters[index].Reference = false;
|
||||
func.Parameters[index].Array = 2;
|
||||
func.Parameters[index].Pointer = 0;
|
||||
func.Parameters[index].Generic = true;
|
||||
func.Parameters[index].CurrentType = "T" + index.ToString();
|
||||
func.Parameters[index].Flow = FlowDirection.Undefined;
|
||||
func.Parameters.Rebuild = true;
|
||||
CreateBody(func, false, enums);
|
||||
yield return new Function(func);
|
||||
|
||||
func.Parameters[index].Reference = false;
|
||||
func.Parameters[index].Array = 3;
|
||||
func.Parameters[index].Pointer = 0;
|
||||
func.Parameters[index].Generic = true;
|
||||
func.Parameters[index].CurrentType = "T" + index.ToString();
|
||||
func.Parameters[index].Flow = FlowDirection.Undefined;
|
||||
func.Parameters.Rebuild = true;
|
||||
CreateBody(func, false, enums);
|
||||
yield return new Function(func);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
foreach (var w in WrapVoidPointers(func, enums))
|
||||
yield return w;
|
||||
--index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WrapReturnType(Function func)
|
||||
{
|
||||
switch (func.ReturnType.WrapperType)
|
||||
{
|
||||
case WrapperTypes.StringReturnType:
|
||||
func.ReturnType.QualifiedType = "String";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
readonly static List<string> handle_statements = new List<string>();
|
||||
readonly static List<string> handle_release_statements = new List<string>();
|
||||
readonly static List<string> fixed_statements = new List<string>();
|
||||
readonly static List<string> assign_statements = new List<string>();
|
||||
|
||||
// For example, if parameter foo has indirection level = 1, then it
|
||||
// is consumed as 'foo*' in the fixed_statements and the call string.
|
||||
readonly static string[] indirection_levels = new string[] { "", "*", "**", "***", "****" };
|
||||
|
||||
static void CreateBody(Function func, bool wantCLSCompliance, EnumCollection enums)
|
||||
{
|
||||
Function f = new Function(func);
|
||||
|
||||
f.Body.Clear();
|
||||
handle_statements.Clear();
|
||||
handle_release_statements.Clear();
|
||||
fixed_statements.Clear();
|
||||
assign_statements.Clear();
|
||||
|
||||
// Obtain pointers by pinning the parameters
|
||||
foreach (Parameter p in f.Parameters)
|
||||
{
|
||||
if (p.NeedsPin)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
// Use GCHandle to obtain pointer to generic parameters and 'fixed' for arrays.
|
||||
// This is because fixed can only take the address of fields, not managed objects.
|
||||
handle_statements.Add(String.Format(
|
||||
"{0} {1}_ptr = {0}.Alloc({1}, GCHandleType.Pinned);",
|
||||
"GCHandle", p.Name));
|
||||
|
||||
handle_release_statements.Add(String.Format("{0}_ptr.Free();", p.Name));
|
||||
|
||||
// Due to the GCHandle-style pinning (which boxes value types), we need to assign the modified
|
||||
// value back to the reference parameter (but only if it has an out or in/out flow direction).
|
||||
if ((p.Flow == FlowDirection.Out || p.Flow == FlowDirection.Undefined) && p.Reference)
|
||||
{
|
||||
assign_statements.Add(String.Format(
|
||||
"{0} = ({1}){0}_ptr.Target;",
|
||||
p.Name, p.QualifiedType));
|
||||
}
|
||||
|
||||
// Note! The following line modifies f.Parameters, *not* this.Parameters
|
||||
p.Name = "(IntPtr)" + p.Name + "_ptr.AddrOfPinnedObject()";
|
||||
}
|
||||
else if (p.WrapperType == WrapperTypes.PointerParameter ||
|
||||
p.WrapperType == WrapperTypes.ArrayParameter ||
|
||||
p.WrapperType == WrapperTypes.ReferenceParameter)
|
||||
{
|
||||
// A fixed statement is issued for all non-generic pointers, arrays and references.
|
||||
fixed_statements.Add(String.Format(
|
||||
"fixed ({0}{3} {1} = {2})",
|
||||
wantCLSCompliance && !p.CLSCompliant ? p.GetCLSCompliantType() : p.QualifiedType,
|
||||
p.Name + "_ptr",
|
||||
p.Array > 0 ? p.Name : "&" + p.Name,
|
||||
indirection_levels[p.IndirectionLevel]));
|
||||
|
||||
if (p.Name == "pixels_ptr")
|
||||
System.Diagnostics.Debugger.Break();
|
||||
|
||||
// Arrays are not value types, so we don't need to do anything for them.
|
||||
// Pointers are passed directly by value, so we don't need to assign them back either (they don't change).
|
||||
if ((p.Flow == FlowDirection.Out || p.Flow == FlowDirection.Undefined) && p.Reference)
|
||||
{
|
||||
assign_statements.Add(String.Format("{0} = *{0}_ptr;", p.Name));
|
||||
}
|
||||
|
||||
p.Name = p.Name + "_ptr";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException("Unknown parameter type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatic OpenGL error checking.
|
||||
// See OpenTK.Graphics.ErrorHelper for more information.
|
||||
// Make sure that no error checking is added to the GetError function,
|
||||
// as that would cause infinite recursion!
|
||||
if ((Settings.Compatibility & Settings.Legacy.NoDebugHelpers) == 0)
|
||||
{
|
||||
if (f.TrimmedName != "GetError")
|
||||
{
|
||||
f.Body.Add("#if DEBUG");
|
||||
f.Body.Add("using (new ErrorHelper(GraphicsContext.CurrentContext))");
|
||||
f.Body.Add("{");
|
||||
if (f.TrimmedName == "Begin")
|
||||
f.Body.Add("GraphicsContext.CurrentContext.ErrorChecking = false;");
|
||||
f.Body.Add("#endif");
|
||||
}
|
||||
}
|
||||
|
||||
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Add("unsafe");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
if (fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.AddRange(fixed_statements);
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
if (handle_statements.Count > 0)
|
||||
{
|
||||
f.Body.AddRange(handle_statements);
|
||||
f.Body.Add("try");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
// Hack: When creating untyped enum wrappers, it is possible that the wrapper uses an "All"
|
||||
// enum, while the delegate uses a specific enum (e.g. "TextureUnit"). For this reason, we need
|
||||
// to modify the parameters before generating the call string.
|
||||
// Note: We cannot generate a callstring using WrappedDelegate directly, as its parameters will
|
||||
// typically be different than the parameters of the wrapper. We need to modify the parameters
|
||||
// of the wrapper directly.
|
||||
if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0)
|
||||
{
|
||||
int parameter_index = -1; // Used for comparing wrapper parameters with delegate parameters
|
||||
foreach (Parameter p in f.Parameters)
|
||||
{
|
||||
parameter_index++;
|
||||
if (IsEnum(p.Name, enums) && p.QualifiedType != f.WrappedDelegate.Parameters[parameter_index].QualifiedType)
|
||||
{
|
||||
p.QualifiedType = f.WrappedDelegate.Parameters[parameter_index].QualifiedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assign_statements.Count > 0)
|
||||
{
|
||||
// Call function
|
||||
string method_call = f.CallString();
|
||||
if (f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", method_call));
|
||||
else if (func.ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
f.Body.Add(String.Format("{0} {1} = null; unsafe {{ {1} = new string((sbyte*){2}); }}",
|
||||
func.ReturnType.QualifiedType, "retval", method_call));
|
||||
else
|
||||
f.Body.Add(String.Format("{0} {1} = {2};", f.ReturnType.QualifiedType, "retval", method_call));
|
||||
|
||||
// Assign out parameters
|
||||
f.Body.AddRange(assign_statements);
|
||||
|
||||
// Return
|
||||
if (!f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
{
|
||||
f.Body.Add("return retval;");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Call function and return
|
||||
if (f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", f.CallString()));
|
||||
else if (func.ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
f.Body.Add(String.Format("unsafe {{ return new string((sbyte*){0}); }}",
|
||||
f.CallString()));
|
||||
else
|
||||
f.Body.Add(String.Format("return {0};", f.CallString()));
|
||||
}
|
||||
|
||||
|
||||
// Free all allocated GCHandles
|
||||
if (handle_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
f.Body.Add("finally");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
|
||||
f.Body.AddRange(handle_release_statements);
|
||||
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if (fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if ((Settings.Compatibility & Settings.Legacy.NoDebugHelpers) == 0)
|
||||
{
|
||||
if (f.TrimmedName != "GetError")
|
||||
{
|
||||
f.Body.Add("#if DEBUG");
|
||||
if (f.TrimmedName == "End")
|
||||
f.Body.Add("GraphicsContext.CurrentContext.ErrorChecking = true;");
|
||||
f.Body.Add("}");
|
||||
f.Body.Add("#endif");
|
||||
}
|
||||
}
|
||||
|
||||
func.Body = f.Body;
|
||||
}
|
||||
|
||||
static bool IsEnum(string s, EnumCollection enums)
|
||||
{
|
||||
return enums.ContainsKey(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,22 +65,16 @@ namespace Bind.GL2
|
|||
|
||||
public virtual void Process()
|
||||
{
|
||||
// Matches functions that cannot have their trailing 'v' trimmed for CLS-Compliance reasons.
|
||||
// Built through trial and error :)
|
||||
//Function.endingsAddV =
|
||||
// new Regex(@"(Coord1|Attrib(I?)1(u?)|Stream1|Uniform2(u?)|(Point|Convolution|Transform|Sprite|List|Combiner|Tex)Parameter|Fog(Coord)?.*|VertexWeight|(Fragment)?Light(Model)?|Material|ReplacementCodeu?b?|Tex(Gen|Env)|Indexu?|TextureParameter.v)",
|
||||
// RegexOptions.Compiled);
|
||||
var overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile));
|
||||
|
||||
Type.Initialize(glTypemap, csTypemap);
|
||||
Enum.Initialize(enumSpec, enumSpecExt);
|
||||
Enum.GLEnums.Translate(new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile)));
|
||||
Function.Initialize();
|
||||
Delegate.Initialize(glSpec, glSpecExt);
|
||||
var enums = ReadEnums(new StreamReader(Path.Combine(Settings.InputPath, enumSpec)));
|
||||
var delegates = ReadDelegates(new StreamReader(Path.Combine(Settings.InputPath, glSpec)));
|
||||
|
||||
WriteBindings(
|
||||
Delegate.Delegates,
|
||||
Function.Wrappers,
|
||||
Enum.GLEnums);
|
||||
enums = new EnumProcessor(overrides).Process(enums);
|
||||
var wrappers = new FuncProcessor(overrides).Process(delegates, enums);
|
||||
|
||||
WriteBindings(delegates, wrappers, enums);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -171,8 +165,6 @@ namespace Bind.GL2
|
|||
}
|
||||
while (!specFile.EndOfStream);
|
||||
|
||||
d.Translate(function_overrides);
|
||||
|
||||
delegates.Add(d);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +446,7 @@ namespace Bind.GL2
|
|||
|
||||
#region void WriteBindings
|
||||
|
||||
public void WriteBindings(DelegateCollection delegates, FunctionCollection functions, EnumCollection enums)
|
||||
public void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums)
|
||||
{
|
||||
Console.WriteLine("Writing bindings to {0}", Settings.OutputPath);
|
||||
if (!Directory.Exists(Settings.OutputPath))
|
||||
|
@ -486,7 +478,7 @@ namespace Bind.GL2
|
|||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
WriteEnums(sw, Enum.GLEnums);
|
||||
WriteEnums(sw, enums);
|
||||
sw.Unindent();
|
||||
|
||||
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None)
|
||||
|
@ -511,7 +503,7 @@ namespace Bind.GL2
|
|||
sw.WriteLine("using System.Runtime.InteropServices;");
|
||||
|
||||
sw.WriteLine("#pragma warning disable 0649");
|
||||
WriteDelegates(sw, Delegate.Delegates);
|
||||
WriteDelegates(sw, delegates);
|
||||
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
|
@ -529,7 +521,7 @@ namespace Bind.GL2
|
|||
sw.WriteLine("using System.Text;");
|
||||
sw.WriteLine("using System.Runtime.InteropServices;");
|
||||
|
||||
WriteImports(sw, Delegate.Delegates);
|
||||
WriteImports(sw, delegates);
|
||||
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
|
@ -547,7 +539,7 @@ namespace Bind.GL2
|
|||
sw.WriteLine("using System.Text;");
|
||||
sw.WriteLine("using System.Runtime.InteropServices;");
|
||||
|
||||
WriteWrappers(sw, Function.Wrappers, Type.CSTypes);
|
||||
WriteWrappers(sw, wrappers, Type.CSTypes);
|
||||
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Bind.Structures;
|
||||
|
||||
|
@ -51,19 +52,20 @@ namespace Bind.Glu
|
|||
|
||||
public override void Process()
|
||||
{
|
||||
Type.Initialize(glTypemap, csTypemap);
|
||||
Enum.Initialize(enumSpec, enumSpecExt, enumSpecAux);
|
||||
Function.Initialize();
|
||||
Delegate.Initialize(glSpec, glSpecExt);
|
||||
throw new NotSupportedException();
|
||||
//Type.Initialize(glTypemap, csTypemap);
|
||||
//Enum.Initialize(enumSpec, enumSpecExt, enumSpecAux);
|
||||
//Function.Initialize();
|
||||
//Delegate.Initialize(glSpec, glSpecExt);
|
||||
|
||||
// Process enums and delegates - create wrappers.
|
||||
Trace.WriteLine("Processing specs, please wait...");
|
||||
//this.Translate();
|
||||
//// Process enums and delegates - create wrappers.
|
||||
//Trace.WriteLine("Processing specs, please wait...");
|
||||
////this.Translate();
|
||||
|
||||
WriteBindings(
|
||||
Delegate.Delegates,
|
||||
Function.Wrappers,
|
||||
Enum.GLEnums);
|
||||
//WriteBindings(
|
||||
// Delegate.Delegates,
|
||||
// Function.Wrappers,
|
||||
// Enum.GLEnums);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Bind.Structures;
|
||||
|
||||
|
@ -48,19 +49,20 @@ namespace Bind.Glx
|
|||
|
||||
public override void Process()
|
||||
{
|
||||
Type.Initialize(glTypemap, csTypemap);
|
||||
Enum.Initialize(enumSpec, enumSpecExt);
|
||||
Function.Initialize();
|
||||
Delegate.Initialize(glSpec, glSpecExt);
|
||||
throw new NotSupportedException();
|
||||
//Type.Initialize(glTypemap, csTypemap);
|
||||
//Enum.Initialize(enumSpec, enumSpecExt);
|
||||
//Function.Initialize();
|
||||
//Delegate.Initialize(glSpec, glSpecExt);
|
||||
|
||||
// Process enums and delegates - create wrappers.
|
||||
Trace.WriteLine("Processing specs, please wait...");
|
||||
//this.Translate();
|
||||
//// Process enums and delegates - create wrappers.
|
||||
//Trace.WriteLine("Processing specs, please wait...");
|
||||
////this.Translate();
|
||||
|
||||
WriteBindings(
|
||||
Delegate.Delegates,
|
||||
Function.Wrappers,
|
||||
Enum.GLEnums);
|
||||
//WriteBindings(
|
||||
// Delegate.Delegates,
|
||||
// Function.Wrappers,
|
||||
// Enum.GLEnums);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace Bind.Structures
|
|||
/// Represents an opengl function.
|
||||
/// The return value, function name, function parameters and opengl version can be retrieved or set.
|
||||
/// </summary>
|
||||
public class Delegate : IComparable<Delegate>
|
||||
class Delegate : IComparable<Delegate>
|
||||
{
|
||||
internal static DelegateCollection Delegates;
|
||||
//internal static DelegateCollection Delegates;
|
||||
|
||||
private static bool delegatesLoaded;
|
||||
bool? cls_compliance_overriden;
|
||||
|
@ -36,14 +36,13 @@ namespace Bind.Structures
|
|||
|
||||
|
||||
#region internal static void Initialize(string glSpec, string glSpecExt)
|
||||
|
||||
internal static void Initialize(string glSpec, string glSpecExt)
|
||||
|
||||
internal static DelegateCollection Initialize(string glSpec, string glSpecExt)
|
||||
{
|
||||
if (!delegatesLoaded)
|
||||
{
|
||||
DelegateCollection delegates = new DelegateCollection();
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, glSpec))
|
||||
{
|
||||
Delegates = MainClass.Generator.ReadDelegates(sr);
|
||||
delegates = MainClass.Generator.ReadDelegates(sr);
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(glSpecExt))
|
||||
|
@ -52,14 +51,13 @@ namespace Bind.Structures
|
|||
{
|
||||
foreach (Delegate d in MainClass.Generator.ReadDelegates(sr).Values)
|
||||
{
|
||||
Utilities.Merge(Delegates, d);
|
||||
Utilities.Merge(delegates, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Enforcing CLS compliance.");
|
||||
MarkCLSCompliance(Function.Wrappers);
|
||||
delegatesLoaded = true;
|
||||
}
|
||||
|
||||
return delegates;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -261,8 +259,6 @@ namespace Bind.Structures
|
|||
|
||||
public string Extension
|
||||
{
|
||||
//get { return _extension; }
|
||||
//set { _extension = value; }
|
||||
get
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Name))
|
||||
|
@ -284,10 +280,9 @@ namespace Bind.Structures
|
|||
|
||||
#endregion
|
||||
|
||||
#region --- Strings ---
|
||||
|
||||
#region public string CallString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents an invocation of this delegate.
|
||||
/// </summary>
|
||||
public string CallString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -301,14 +296,10 @@ namespace Bind.Structures
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representing the full non-delegate declaration without decorations.
|
||||
/// (ie "(unsafe) void glXxxYyy(int a, float b, IntPtr c)"
|
||||
/// </summary>
|
||||
#region public string DeclarationString()
|
||||
|
||||
public string DeclarationString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -322,10 +313,6 @@ namespace Bind.Structures
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region override public string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representing the full delegate declaration without decorations.
|
||||
/// (ie "(unsafe) void delegate glXxxYyy(int a, float b, IntPtr c)"
|
||||
|
@ -344,8 +331,6 @@ namespace Bind.Structures
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Delegate GetCLSCompliantDelegate()
|
||||
{
|
||||
Delegate f = new Delegate(this);
|
||||
|
@ -360,286 +345,6 @@ namespace Bind.Structures
|
|||
return f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Wrapper Creation ---
|
||||
|
||||
#region MarkCLSCompliance
|
||||
|
||||
static void MarkCLSCompliance(FunctionCollection collection)
|
||||
{
|
||||
foreach (List<Function> wrappers in Function.Wrappers.Values)
|
||||
{
|
||||
restart:
|
||||
for (int i = 0; i < wrappers.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < wrappers.Count; j++)
|
||||
{
|
||||
if (wrappers[i].TrimmedName == wrappers[j].TrimmedName && wrappers[i].Parameters.Count == wrappers[j].Parameters.Count)
|
||||
{
|
||||
bool function_i_is_problematic = false;
|
||||
bool function_j_is_problematic = false;
|
||||
|
||||
int k;
|
||||
for (k = 0; k < wrappers[i].Parameters.Count; k++)
|
||||
{
|
||||
if (wrappers[i].Parameters[k].CurrentType != wrappers[j].Parameters[k].CurrentType)
|
||||
break;
|
||||
|
||||
if (wrappers[i].Parameters[k].DiffersOnlyOnReference(wrappers[j].Parameters[k]))
|
||||
if (wrappers[i].Parameters[k].Reference)
|
||||
function_i_is_problematic = true;
|
||||
else
|
||||
function_j_is_problematic = true;
|
||||
}
|
||||
|
||||
if (k == wrappers[i].Parameters.Count)
|
||||
{
|
||||
if (function_i_is_problematic)
|
||||
wrappers.RemoveAt(i);
|
||||
//wrappers[i].CLSCompliant = false;
|
||||
if (function_j_is_problematic)
|
||||
wrappers.RemoveAt(j);
|
||||
//wrappers[j].CLSCompliant = false;
|
||||
|
||||
if (function_i_is_problematic || function_j_is_problematic)
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateWrappers
|
||||
|
||||
void CreateWrappers()
|
||||
{
|
||||
List<Function> wrappers = new List<Function>();
|
||||
CreateNormalWrappers(wrappers);
|
||||
|
||||
// Generate wrappers using the untyped enum parameters, if necessary.
|
||||
if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0)
|
||||
{
|
||||
CreateUntypedEnumWrappers(wrappers);
|
||||
}
|
||||
|
||||
// Add CLS-compliant overloads for non-CLS compliant wrappers.
|
||||
CreateCLSCompliantWrappers(wrappers);
|
||||
}
|
||||
|
||||
private static void CreateCLSCompliantWrappers(List<Function> wrappers)
|
||||
{
|
||||
// If the function is not CLS-compliant (e.g. it contains unsigned parameters)
|
||||
// we need to create a CLS-Compliant overload. However, we should only do this
|
||||
// iff the opengl function does not contain unsigned/signed overloads itself
|
||||
// to avoid redefinitions.
|
||||
foreach (Function f in wrappers)
|
||||
{
|
||||
Function.Wrappers.AddChecked(f);
|
||||
|
||||
if (!f.CLSCompliant)
|
||||
{
|
||||
Function cls = new Function(f);
|
||||
|
||||
cls.Body.Clear();
|
||||
cls.CreateBody(true);
|
||||
|
||||
bool modified = false;
|
||||
for (int i = 0; i < f.Parameters.Count; i++)
|
||||
{
|
||||
cls.Parameters[i].CurrentType = cls.Parameters[i].GetCLSCompliantType();
|
||||
if (cls.Parameters[i].CurrentType != f.Parameters[i].CurrentType)
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified)
|
||||
Function.Wrappers.AddChecked(cls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateUntypedEnumWrappers(List<Function> wrappers)
|
||||
{
|
||||
Function f = new Function(this);
|
||||
var modified = false;
|
||||
f.Parameters = new ParameterCollection(f.Parameters.Select(p =>
|
||||
{
|
||||
if (p.IsEnum && p.CurrentType != Settings.CompleteEnumName)
|
||||
{
|
||||
p.CurrentType = Settings.CompleteEnumName;
|
||||
modified = true;
|
||||
}
|
||||
return p;
|
||||
}));
|
||||
if (modified)
|
||||
{
|
||||
f.WrapReturnType();
|
||||
f.WrapParameters(wrappers);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateNormalWrappers(List<Function> wrappers)
|
||||
{
|
||||
Function f = new Function(this);
|
||||
f.WrapReturnType();
|
||||
f.WrapParameters(wrappers);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TrimName
|
||||
|
||||
// Trims unecessary suffices from the specified OpenGL function name.
|
||||
protected static string TrimName(string name, bool keep_extension)
|
||||
{
|
||||
string trimmed_name = Utilities.StripGL2Extension(name);
|
||||
string extension = Utilities.GetGL2Extension(name);
|
||||
|
||||
// Note: some endings should not be trimmed, for example: 'b' from Attrib.
|
||||
// Check the endingsNotToTrim regex for details.
|
||||
Match m = endingsNotToTrim.Match(trimmed_name);
|
||||
if ((m.Index + m.Length) != trimmed_name.Length)
|
||||
{
|
||||
m = endings.Match(trimmed_name);
|
||||
|
||||
if (m.Length > 0 && m.Index + m.Length == trimmed_name.Length)
|
||||
{
|
||||
// Only trim endings, not internal matches.
|
||||
if (m.Value[m.Length - 1] == 'v' && endingsAddV.IsMatch(name) &&
|
||||
!name.StartsWith("Get") && !name.StartsWith("MatrixIndex"))
|
||||
{
|
||||
// Only trim ending 'v' when there is a number
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index) + "v";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!trimmed_name.EndsWith("xedv"))
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index);
|
||||
else
|
||||
trimmed_name = trimmed_name.Substring(0, m.Index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_extension)
|
||||
return trimmed_name + extension;
|
||||
else
|
||||
return trimmed_name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TranslateReturnType
|
||||
|
||||
// Translates the opengl return type to the equivalent C# type.
|
||||
//
|
||||
// First, we use the official typemap (gl.tm) to get the correct type.
|
||||
// Then we override this, when it is:
|
||||
// 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption)
|
||||
// 2) An array (translates to IntPtr)
|
||||
// 3) A generic object or void* (translates to IntPtr)
|
||||
// 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise).
|
||||
// Return types must always be CLS-compliant, because .Net does not support overloading on return types.
|
||||
void TranslateReturnType(XPathNavigator overrides, XPathNavigator function_override)
|
||||
{
|
||||
if (function_override != null)
|
||||
{
|
||||
XPathNavigator return_override = function_override.SelectSingleNode("returns");
|
||||
if (return_override != null)
|
||||
{
|
||||
ReturnType.CurrentType = return_override.Value;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnType.Translate(overrides, Category);
|
||||
|
||||
if (ReturnType.CurrentType.ToLower().Contains("void") && ReturnType.Pointer != 0)
|
||||
{
|
||||
ReturnType.QualifiedType = "System.IntPtr";
|
||||
ReturnType.WrapperType = WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
{
|
||||
ReturnType.QualifiedType = "System.IntPtr";
|
||||
ReturnType.WrapperType = WrapperTypes.StringReturnType;
|
||||
}
|
||||
|
||||
if (ReturnType.CurrentType.ToLower().Contains("object"))
|
||||
{
|
||||
ReturnType.QualifiedType = "System.IntPtr";
|
||||
ReturnType.WrapperType |= WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (ReturnType.CurrentType.Contains("GLenum"))
|
||||
{
|
||||
if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None)
|
||||
ReturnType.QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, Settings.CompleteEnumName);
|
||||
else
|
||||
ReturnType.QualifiedType = "int";
|
||||
}
|
||||
|
||||
ReturnType.CurrentType = ReturnType.GetCLSCompliantType();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TranslateParameters
|
||||
|
||||
protected virtual void TranslateParameters(XPathNavigator overrides, XPathNavigator function_override)
|
||||
{
|
||||
for (int i = 0; i < Parameters.Count; i++)
|
||||
{
|
||||
if (function_override != null)
|
||||
{
|
||||
XPathNavigator param_override = function_override.SelectSingleNode(String.Format("param[@name='{0}']", Parameters[i].Name));
|
||||
if (param_override != null)
|
||||
{
|
||||
foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element))
|
||||
{
|
||||
switch (node.Name)
|
||||
{
|
||||
case "type": Parameters[i].CurrentType = (string)node.TypedValue; break;
|
||||
case "name": Parameters[i].Name = (string)node.TypedValue; break;
|
||||
case "flow": Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Parameters[i].Translate(overrides, Category);
|
||||
if (Parameters[i].CurrentType == "UInt16" && Name.Contains("LineStipple"))
|
||||
Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
|
||||
|
||||
// Special case: these functions take a string[] that should stay as is.
|
||||
// Todo: move to gloverrides.xml
|
||||
//if (Name.Contains("ShaderSource") && Parameters[i].CurrentType.ToLower().Contains("string"))
|
||||
// Parameters[i].Array = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal void Translate(XPathDocument overrides)
|
||||
{
|
||||
if (overrides == null)
|
||||
throw new ArgumentNullException("overrides");
|
||||
|
||||
string path = "/overrides/replace/function[@name='{0}' and @extension='{1}']";
|
||||
string name = TrimName(Name, false);
|
||||
XPathNavigator function_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name, Extension));
|
||||
|
||||
TranslateReturnType(overrides.CreateNavigator(), function_override);
|
||||
TranslateParameters(overrides.CreateNavigator(), function_override);
|
||||
|
||||
CreateWrappers();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IComparable<Delegate> Members
|
||||
|
||||
public int CompareTo(Delegate other)
|
||||
|
|
|
@ -17,66 +17,10 @@ namespace Bind.Structures
|
|||
|
||||
public class Enum
|
||||
{
|
||||
internal static EnumCollection GLEnums = new EnumCollection();
|
||||
internal static EnumCollection AuxEnums = new EnumCollection();
|
||||
|
||||
static StringBuilder translator = new StringBuilder();
|
||||
string _name, _type;
|
||||
static bool enumsLoaded;
|
||||
|
||||
#region Initialize
|
||||
|
||||
internal static void Initialize(string enumFile, string enumextFile, string auxFile)
|
||||
{
|
||||
Initialize(enumFile, enumextFile);
|
||||
|
||||
if (!String.IsNullOrEmpty(auxFile))
|
||||
using (StreamReader sr = new StreamReader(Path.Combine(Settings.InputPath, auxFile)))
|
||||
{
|
||||
AuxEnums = MainClass.Generator.ReadEnums(sr);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Initialize(string enumFile, string enumextFile)
|
||||
{
|
||||
if (!enumsLoaded)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(enumFile))
|
||||
{
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, enumFile))
|
||||
{
|
||||
GLEnums = MainClass.Generator.ReadEnums(sr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(enumextFile))
|
||||
{
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, enumextFile))
|
||||
{
|
||||
foreach (Enum e in MainClass.Generator.ReadEnums(sr).Values)
|
||||
{
|
||||
//enums.Add(e.Name, e);
|
||||
Utilities.Merge(GLEnums, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enumsLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Enum()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
// Returns true if the enum contains a collection of flags, i.e. 1, 2, 4, 8, ...
|
||||
public bool IsFlagCollection
|
||||
{
|
||||
|
@ -89,8 +33,6 @@ namespace Bind.Structures
|
|||
}
|
||||
}
|
||||
|
||||
#region public string Name
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name ?? ""; }
|
||||
|
@ -104,10 +46,6 @@ namespace Bind.Structures
|
|||
set { _type = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ConstantCollection
|
||||
|
||||
Dictionary<string, Constant> _constant_collection = new Dictionary<string, Constant>();
|
||||
|
||||
public IDictionary<string, Constant> ConstantCollection
|
||||
|
@ -126,66 +64,6 @@ namespace Bind.Structures
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TranslateName
|
||||
|
||||
// Translate the constant's name to match .Net naming conventions
|
||||
[Obsolete]
|
||||
public static string TranslateName(string name)
|
||||
{
|
||||
if (String.IsNullOrEmpty(name))
|
||||
return name;
|
||||
|
||||
if (Utilities.Keywords.Contains(name))
|
||||
return name;
|
||||
|
||||
translator.Remove(0, translator.Length); // Trick to avoid allocating a new StringBuilder.
|
||||
|
||||
if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None)
|
||||
{
|
||||
// Detect if we just passed a '_' or a number and make the next char uppercase.
|
||||
bool is_after_underscore_or_number = true;
|
||||
// Detect if previous character was uppercase, and turn the current one to lowercase.
|
||||
bool is_previous_uppercase = false;
|
||||
|
||||
foreach (char c in name)
|
||||
{
|
||||
char char_to_add;
|
||||
if (c == '_' || c == '-')
|
||||
is_after_underscore_or_number = true;
|
||||
else
|
||||
{
|
||||
if (Char.IsDigit(c))
|
||||
is_after_underscore_or_number = true;
|
||||
|
||||
char_to_add = is_after_underscore_or_number ? Char.ToUpper(c) :
|
||||
is_previous_uppercase ? Char.ToLower(c) : c;
|
||||
translator.Append(char_to_add);
|
||||
|
||||
is_previous_uppercase = Char.IsUpper(c);
|
||||
is_after_underscore_or_number = false;
|
||||
}
|
||||
}
|
||||
|
||||
translator[0] = Char.ToUpper(translator[0]);
|
||||
}
|
||||
else
|
||||
translator.Append(name);
|
||||
|
||||
translator.Replace("Pname", "PName");
|
||||
translator.Replace("SRgb", "Srgb");
|
||||
|
||||
string ret = translator.ToString();
|
||||
if (ret.StartsWith(Settings.EnumPrefix))
|
||||
return ret.Substring(Settings.EnumPrefix.Length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToString
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -217,10 +95,6 @@ namespace Bind.Structures
|
|||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -235,141 +109,6 @@ namespace Bind.Structures
|
|||
Utilities.Merge(this, e);
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal void Translate(XPathDocument overrides)
|
||||
{
|
||||
if (overrides == null)
|
||||
throw new ArgumentNullException("overrides");
|
||||
|
||||
string path = "/overrides/replace/enum[@name='{0}']";
|
||||
|
||||
// Translate enum names.
|
||||
{
|
||||
List<string> keys_to_update = new List<string>();
|
||||
foreach (Enum e in Values)
|
||||
{
|
||||
string name = e.Name;
|
||||
|
||||
XPathNavigator enum_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name));
|
||||
if (enum_override != null)
|
||||
{
|
||||
XPathNavigator name_override = enum_override.SelectSingleNode("name");
|
||||
if (name_override != null)
|
||||
{
|
||||
name = name_override.Value;
|
||||
}
|
||||
}
|
||||
|
||||
name = EnumProcessor.TranslateEnumName(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];
|
||||
Remove(name);
|
||||
Add(e.Name, e);
|
||||
}
|
||||
|
||||
keys_to_update = null;
|
||||
}
|
||||
|
||||
foreach (Enum e in Values)
|
||||
{
|
||||
XPathNavigator enum_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, e.Name));
|
||||
foreach (Constant c in e.ConstantCollection.Values)
|
||||
{
|
||||
if (enum_override != null)
|
||||
{
|
||||
XPathNavigator constant_override = enum_override.SelectSingleNode(String.Format("token[@name='{0}']", c.PreviousName)) ??
|
||||
enum_override.SelectSingleNode(String.Format("token[@name={0}]", c.Name));
|
||||
if (constant_override != null)
|
||||
{
|
||||
foreach (XPathNavigator node in constant_override.SelectChildren(XPathNodeType.Element))
|
||||
{
|
||||
switch (node.Name)
|
||||
{
|
||||
case "name": c.Name = (string)node.TypedValue; break;
|
||||
case "value": c.Value = (string)node.TypedValue; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There are cases when a value is an aliased constant, with no enum specified.
|
||||
// (e.g. FOG_COORD_ARRAY_TYPE = GL_FOG_COORDINATE_ARRAY_TYPE)
|
||||
// In this case try searching all enums for the correct constant to alias (stupid opengl specs).
|
||||
if (String.IsNullOrEmpty(c.Reference) && !Char.IsDigit(c.Value[0]))
|
||||
{
|
||||
foreach (Enum @enum in Values)
|
||||
{
|
||||
// Skip generic GLenum
|
||||
if (@enum.Name == "GLenum")
|
||||
continue;
|
||||
|
||||
if (@enum.ConstantCollection.ContainsKey(c.Value))
|
||||
{
|
||||
c.Reference = @enum.Name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Enum e in Values)
|
||||
{
|
||||
restart:
|
||||
foreach (Constant c in e.ConstantCollection.Values)
|
||||
{
|
||||
bool result = Constant.TranslateConstantWithReference(c, Enum.GLEnums, Enum.AuxEnums);
|
||||
if (!result)
|
||||
{
|
||||
e.ConstantCollection.Remove(c.Name);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.DropMultipleTokens)
|
||||
{
|
||||
// When there are multiple tokens with the same value but different extension
|
||||
// drop the duplicates. Order of preference: core > ARB > EXT > vendor specific
|
||||
|
||||
List<Constant> removed_tokens = new List<Constant>();
|
||||
|
||||
foreach (Enum e in Values)
|
||||
{
|
||||
if (e.Name == "All")
|
||||
continue;
|
||||
|
||||
// This implementation is a not very bright O(n^2).
|
||||
foreach (Constant c in e.ConstantCollection.Values)
|
||||
{
|
||||
foreach (Constant c2 in e.ConstantCollection.Values)
|
||||
{
|
||||
if (c.Name != c2.Name && c.Value == c2.Value)
|
||||
{
|
||||
int prefer = OrderOfPreference(Utilities.GetGL2Extension(c.Name), Utilities.GetGL2Extension(c2.Name));
|
||||
if (prefer == -1)
|
||||
removed_tokens.Add(c2);
|
||||
else if (prefer == 1)
|
||||
removed_tokens.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Constant c in removed_tokens)
|
||||
e.ConstantCollection.Remove(c.Name);
|
||||
removed_tokens.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return -1 for ext1, 1 for ext2 or 0 if no preference.
|
||||
int OrderOfPreference(string ext1, string ext2)
|
||||
{
|
||||
|
|
|
@ -11,29 +11,8 @@ using System.Text.RegularExpressions;
|
|||
|
||||
namespace Bind.Structures
|
||||
{
|
||||
public class Function : Delegate, IEquatable<Function>, IComparable<Function>
|
||||
class Function : Delegate, IEquatable<Function>, IComparable<Function>
|
||||
{
|
||||
#region Static Members
|
||||
|
||||
internal static FunctionCollection Wrappers;
|
||||
|
||||
static bool loaded;
|
||||
|
||||
#region internal static void Initialize()
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
if (!loaded)
|
||||
{
|
||||
Wrappers = new FunctionCollection();
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
Delegate wrapped_delegate;
|
||||
|
@ -239,369 +218,6 @@ namespace Bind.Structures
|
|||
|
||||
#endregion
|
||||
|
||||
#region public void WrapParameters(List<Function> wrappers)
|
||||
|
||||
public void WrapParameters(List<Function> wrappers)
|
||||
{
|
||||
Function f;
|
||||
|
||||
if (Parameters.HasPointerParameters)
|
||||
{
|
||||
Function _this = new Function(this);
|
||||
// Array overloads
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter && p.ElementCount != 1)
|
||||
{
|
||||
p.Reference = false;
|
||||
p.Array++;
|
||||
p.Pointer--;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
f.CreateBody(false);
|
||||
wrappers.Add(f);
|
||||
new Function(f).WrapVoidPointers(wrappers);
|
||||
|
||||
_this = new Function(this);
|
||||
// Reference overloads
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter)
|
||||
{
|
||||
p.Reference = true;
|
||||
p.Array--;
|
||||
p.Pointer--;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
f.CreateBody(false);
|
||||
wrappers.Add(f);
|
||||
new Function(f).WrapVoidPointers(wrappers);
|
||||
|
||||
_this = this;
|
||||
// Pointer overloads
|
||||
// Should be last to work around Intellisense bug, where
|
||||
// array overloads are not reported if there is a pointer overload.
|
||||
foreach (Parameter p in _this.Parameters)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.ArrayParameter)
|
||||
{
|
||||
p.Reference = false;
|
||||
//p.Array--;
|
||||
//p.Pointer++;
|
||||
}
|
||||
}
|
||||
f = new Function(_this);
|
||||
f.CreateBody(false);
|
||||
wrappers.Add(f);
|
||||
new Function(f).WrapVoidPointers(wrappers);
|
||||
}
|
||||
else
|
||||
{
|
||||
f = new Function(this);
|
||||
f.CreateBody(false);
|
||||
wrappers.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void WrapVoidPointers(List<Function> wrappers)
|
||||
|
||||
public void WrapVoidPointers(List<Function> wrappers)
|
||||
{
|
||||
if (index >= 0 && index < Parameters.Count)
|
||||
{
|
||||
if (Parameters[index].WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
WrapVoidPointers(wrappers);
|
||||
--index;
|
||||
|
||||
// On stack rewind, create generic wrappers
|
||||
Parameters[index].Reference = true;
|
||||
Parameters[index].Array = 0;
|
||||
Parameters[index].Pointer = 0;
|
||||
Parameters[index].Generic = true;
|
||||
Parameters[index].CurrentType = "T" + index.ToString();
|
||||
Parameters[index].Flow = FlowDirection.Undefined;
|
||||
Parameters.Rebuild = true;
|
||||
CreateBody(false);
|
||||
wrappers.Add(new Function(this));
|
||||
|
||||
Parameters[index].Reference = false;
|
||||
Parameters[index].Array = 1;
|
||||
Parameters[index].Pointer = 0;
|
||||
Parameters[index].Generic = true;
|
||||
Parameters[index].CurrentType = "T" + index.ToString();
|
||||
Parameters[index].Flow = FlowDirection.Undefined;
|
||||
Parameters.Rebuild = true;
|
||||
CreateBody(false);
|
||||
wrappers.Add(new Function(this));
|
||||
|
||||
Parameters[index].Reference = false;
|
||||
Parameters[index].Array = 2;
|
||||
Parameters[index].Pointer = 0;
|
||||
Parameters[index].Generic = true;
|
||||
Parameters[index].CurrentType = "T" + index.ToString();
|
||||
Parameters[index].Flow = FlowDirection.Undefined;
|
||||
Parameters.Rebuild = true;
|
||||
CreateBody(false);
|
||||
wrappers.Add(new Function(this));
|
||||
|
||||
Parameters[index].Reference = false;
|
||||
Parameters[index].Array = 3;
|
||||
Parameters[index].Pointer = 0;
|
||||
Parameters[index].Generic = true;
|
||||
Parameters[index].CurrentType = "T" + index.ToString();
|
||||
Parameters[index].Flow = FlowDirection.Undefined;
|
||||
Parameters.Rebuild = true;
|
||||
CreateBody(false);
|
||||
wrappers.Add(new Function(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
WrapVoidPointers(wrappers);
|
||||
--index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void WrapReturnType()
|
||||
|
||||
public void WrapReturnType()
|
||||
{
|
||||
switch (ReturnType.WrapperType)
|
||||
{
|
||||
case WrapperTypes.StringReturnType:
|
||||
ReturnType.QualifiedType = "String";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public void CreateBody(bool wantCLSCompliance)
|
||||
|
||||
readonly static List<string> handle_statements = new List<string>();
|
||||
readonly static List<string> handle_release_statements = new List<string>();
|
||||
readonly static List<string> fixed_statements = new List<string>();
|
||||
readonly static List<string> assign_statements = new List<string>();
|
||||
|
||||
// For example, if parameter foo has indirection level = 1, then it
|
||||
// is consumed as 'foo*' in the fixed_statements and the call string.
|
||||
string[] indirection_levels = new string[] { "", "*", "**", "***", "****" };
|
||||
|
||||
public void CreateBody(bool wantCLSCompliance)
|
||||
{
|
||||
Function f = new Function(this);
|
||||
|
||||
f.Body.Clear();
|
||||
handle_statements.Clear();
|
||||
handle_release_statements.Clear();
|
||||
fixed_statements.Clear();
|
||||
assign_statements.Clear();
|
||||
|
||||
// Obtain pointers by pinning the parameters
|
||||
foreach (Parameter p in f.Parameters)
|
||||
{
|
||||
if (p.NeedsPin)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
// Use GCHandle to obtain pointer to generic parameters and 'fixed' for arrays.
|
||||
// This is because fixed can only take the address of fields, not managed objects.
|
||||
handle_statements.Add(String.Format(
|
||||
"{0} {1}_ptr = {0}.Alloc({1}, GCHandleType.Pinned);",
|
||||
"GCHandle", p.Name));
|
||||
|
||||
handle_release_statements.Add(String.Format("{0}_ptr.Free();", p.Name));
|
||||
|
||||
// Due to the GCHandle-style pinning (which boxes value types), we need to assign the modified
|
||||
// value back to the reference parameter (but only if it has an out or in/out flow direction).
|
||||
if ((p.Flow == FlowDirection.Out || p.Flow == FlowDirection.Undefined) && p.Reference)
|
||||
{
|
||||
assign_statements.Add(String.Format(
|
||||
"{0} = ({1}){0}_ptr.Target;",
|
||||
p.Name, p.QualifiedType));
|
||||
}
|
||||
|
||||
// Note! The following line modifies f.Parameters, *not* this.Parameters
|
||||
p.Name = "(IntPtr)" + p.Name + "_ptr.AddrOfPinnedObject()";
|
||||
}
|
||||
else if (p.WrapperType == WrapperTypes.PointerParameter ||
|
||||
p.WrapperType == WrapperTypes.ArrayParameter ||
|
||||
p.WrapperType == WrapperTypes.ReferenceParameter)
|
||||
{
|
||||
// A fixed statement is issued for all non-generic pointers, arrays and references.
|
||||
fixed_statements.Add(String.Format(
|
||||
"fixed ({0}{3} {1} = {2})",
|
||||
wantCLSCompliance && !p.CLSCompliant ? p.GetCLSCompliantType() : p.QualifiedType,
|
||||
p.Name + "_ptr",
|
||||
p.Array > 0 ? p.Name : "&" + p.Name,
|
||||
indirection_levels[p.IndirectionLevel]));
|
||||
|
||||
if (p.Name == "pixels_ptr")
|
||||
System.Diagnostics.Debugger.Break();
|
||||
|
||||
// Arrays are not value types, so we don't need to do anything for them.
|
||||
// Pointers are passed directly by value, so we don't need to assign them back either (they don't change).
|
||||
if ((p.Flow == FlowDirection.Out || p.Flow == FlowDirection.Undefined) && p.Reference)
|
||||
{
|
||||
assign_statements.Add(String.Format("{0} = *{0}_ptr;", p.Name));
|
||||
}
|
||||
|
||||
p.Name = p.Name + "_ptr";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ApplicationException("Unknown parameter type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatic OpenGL error checking.
|
||||
// See OpenTK.Graphics.ErrorHelper for more information.
|
||||
// Make sure that no error checking is added to the GetError function,
|
||||
// as that would cause infinite recursion!
|
||||
if ((Settings.Compatibility & Settings.Legacy.NoDebugHelpers) == 0)
|
||||
{
|
||||
if (f.TrimmedName != "GetError")
|
||||
{
|
||||
f.Body.Add("#if DEBUG");
|
||||
f.Body.Add("using (new ErrorHelper(GraphicsContext.CurrentContext))");
|
||||
f.Body.Add("{");
|
||||
if (f.TrimmedName == "Begin")
|
||||
f.Body.Add("GraphicsContext.CurrentContext.ErrorChecking = false;");
|
||||
f.Body.Add("#endif");
|
||||
}
|
||||
}
|
||||
|
||||
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Add("unsafe");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
if (fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.AddRange(fixed_statements);
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
if (handle_statements.Count > 0)
|
||||
{
|
||||
f.Body.AddRange(handle_statements);
|
||||
f.Body.Add("try");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
}
|
||||
|
||||
// Hack: When creating untyped enum wrappers, it is possible that the wrapper uses an "All"
|
||||
// enum, while the delegate uses a specific enum (e.g. "TextureUnit"). For this reason, we need
|
||||
// to modify the parameters before generating the call string.
|
||||
// Note: We cannot generate a callstring using WrappedDelegate directly, as its parameters will
|
||||
// typically be different than the parameters of the wrapper. We need to modify the parameters
|
||||
// of the wrapper directly.
|
||||
if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0)
|
||||
{
|
||||
int parameter_index = -1; // Used for comparing wrapper parameters with delegate parameters
|
||||
foreach (Parameter p in f.Parameters)
|
||||
{
|
||||
parameter_index++;
|
||||
if (p.IsEnum && p.QualifiedType != f.WrappedDelegate.Parameters[parameter_index].QualifiedType)
|
||||
{
|
||||
p.QualifiedType = f.WrappedDelegate.Parameters[parameter_index].QualifiedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (assign_statements.Count > 0)
|
||||
{
|
||||
// Call function
|
||||
string method_call = f.CallString();
|
||||
if (f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", method_call));
|
||||
else if (ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
f.Body.Add(String.Format("{0} {1} = null; unsafe {{ {1} = new string((sbyte*){2}); }}",
|
||||
ReturnType.QualifiedType, "retval", method_call));
|
||||
else
|
||||
f.Body.Add(String.Format("{0} {1} = {2};", f.ReturnType.QualifiedType, "retval", method_call));
|
||||
|
||||
// Assign out parameters
|
||||
f.Body.AddRange(assign_statements);
|
||||
|
||||
// Return
|
||||
if (!f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
{
|
||||
f.Body.Add("return retval;");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Call function and return
|
||||
if (f.ReturnType.CurrentType.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", f.CallString()));
|
||||
else if (ReturnType.CurrentType.ToLower().Contains("string"))
|
||||
f.Body.Add(String.Format("unsafe {{ return new string((sbyte*){0}); }}",
|
||||
f.CallString()));
|
||||
else
|
||||
f.Body.Add(String.Format("return {0};", f.CallString()));
|
||||
}
|
||||
|
||||
|
||||
// Free all allocated GCHandles
|
||||
if (handle_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
f.Body.Add("finally");
|
||||
f.Body.Add("{");
|
||||
f.Body.Indent();
|
||||
|
||||
f.Body.AddRange(handle_release_statements);
|
||||
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if (fixed_statements.Count > 0)
|
||||
{
|
||||
f.Body.Unindent();
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
if ((Settings.Compatibility & Settings.Legacy.NoDebugHelpers) == 0)
|
||||
{
|
||||
if (f.TrimmedName != "GetError")
|
||||
{
|
||||
f.Body.Add("#if DEBUG");
|
||||
if (f.TrimmedName == "End")
|
||||
f.Body.Add("GraphicsContext.CurrentContext.ErrorChecking = true;");
|
||||
f.Body.Add("}");
|
||||
f.Body.Add("#endif");
|
||||
}
|
||||
}
|
||||
|
||||
Body = f.Body;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IComparable<Function> Members
|
||||
|
||||
public int CompareTo(Function other)
|
||||
|
@ -712,27 +328,27 @@ namespace Bind.Structures
|
|||
/// <param name="f">The Function to add.</param>
|
||||
public void AddChecked(Function f)
|
||||
{
|
||||
if (Function.Wrappers.ContainsKey(f.Extension))
|
||||
if (ContainsKey(f.Extension))
|
||||
{
|
||||
int index = Function.Wrappers[f.Extension].IndexOf(f);
|
||||
int index = this[f.Extension].IndexOf(f);
|
||||
if (index == -1)
|
||||
{
|
||||
Function.Wrappers.Add(f);
|
||||
Add(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Function existing = Function.Wrappers[f.Extension][index];
|
||||
Function existing = this[f.Extension][index];
|
||||
if ((existing.Parameters.HasUnsignedParameters && !unsignedFunctions.IsMatch(existing.Name) && unsignedFunctions.IsMatch(f.Name)) ||
|
||||
(!existing.Parameters.HasUnsignedParameters && unsignedFunctions.IsMatch(existing.Name) && !unsignedFunctions.IsMatch(f.Name)))
|
||||
{
|
||||
Function.Wrappers[f.Extension].RemoveAt(index);
|
||||
Function.Wrappers[f.Extension].Add(f);
|
||||
this[f.Extension].RemoveAt(index);
|
||||
this[f.Extension].Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Function.Wrappers.Add(f);
|
||||
Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,11 +281,11 @@ namespace Bind.Structures
|
|||
|
||||
#endregion
|
||||
|
||||
#region override public void Translate(XPathNavigator overrides, string category)
|
||||
#region Translate()
|
||||
|
||||
override public void Translate(XPathNavigator overrides, string category)
|
||||
override public void Translate(XPathNavigator overrides, string category, EnumCollection enums)
|
||||
{
|
||||
base.Translate(overrides, category);
|
||||
base.Translate(overrides, category, enums);
|
||||
|
||||
// Find out the necessary wrapper types.
|
||||
if (Pointer != 0)/* || CurrentType == "IntPtr")*/
|
||||
|
|
|
@ -204,15 +204,15 @@ namespace Bind.Structures
|
|||
|
||||
#endregion
|
||||
|
||||
// Returns true if parameter is an enum.
|
||||
public bool IsEnum
|
||||
{
|
||||
get
|
||||
{
|
||||
return Enum.GLEnums.ContainsKey(CurrentType) ||
|
||||
Enum.AuxEnums.ContainsKey(CurrentType);
|
||||
}
|
||||
}
|
||||
//// Returns true if parameter is an enum.
|
||||
//public bool IsEnum
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// return Enum.GLEnums.ContainsKey(CurrentType) ||
|
||||
// Enum.AuxEnums.ContainsKey(CurrentType);
|
||||
// }
|
||||
//}
|
||||
|
||||
#region IndirectionLevel
|
||||
|
||||
|
@ -351,32 +351,34 @@ namespace Bind.Structures
|
|||
|
||||
#region public virtual void Translate(XPathNavigator overrides, string category)
|
||||
|
||||
public virtual void Translate(XPathNavigator overrides, string category)
|
||||
public virtual void Translate(XPathNavigator overrides, string category, EnumCollection enums)
|
||||
{
|
||||
Enum @enum;
|
||||
string s;
|
||||
|
||||
|
||||
|
||||
// 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.
|
||||
// Special case for Boolean - it is an enum, but it is dumb to use that instead of the 'bool' type.
|
||||
bool normal = false;
|
||||
bool aux = false;
|
||||
normal = Enum.GLEnums.TryGetValue(CurrentType, out @enum);
|
||||
if (!normal)
|
||||
aux = Enum.AuxEnums != null && Enum.AuxEnums.TryGetValue(CurrentType, out @enum);
|
||||
bool normal = enums.TryGetValue(CurrentType, out @enum);
|
||||
//bool aux = enums.TryGetValue(EnumProcessor.TranslateEnumName(CurrentType), out @enum);
|
||||
|
||||
// Translate enum types
|
||||
if ((normal || aux) && @enum.Name != "GLenum" && @enum.Name != "Boolean")
|
||||
if ((normal /*|| aux*/) && @enum.Name != "GLenum" && @enum.Name != "Boolean")
|
||||
{
|
||||
if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None)
|
||||
{
|
||||
QualifiedType = "int";
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (aux)
|
||||
// CurrentType = EnumProcessor.TranslateEnumName(CurrentType);
|
||||
|
||||
#warning "Unecessary code"
|
||||
if (normal)
|
||||
QualifiedType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsOutput));
|
||||
else if (aux)
|
||||
QualifiedType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsAuxOutput));
|
||||
}
|
||||
}
|
||||
else if (GLTypes.TryGetValue(CurrentType, out s))
|
||||
|
@ -392,7 +394,7 @@ namespace Bind.Structures
|
|||
else
|
||||
{
|
||||
// Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc)
|
||||
if (Enum.GLEnums.ContainsKey(category))
|
||||
if (enums.ContainsKey(category))
|
||||
{
|
||||
QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, EnumProcessor.TranslateEnumName(category));
|
||||
}
|
||||
|
@ -410,30 +412,7 @@ namespace Bind.Structures
|
|||
case "string": QualifiedType = "String"; break;
|
||||
}
|
||||
|
||||
#warning "Stale code"
|
||||
// This is not enum, default translation:
|
||||
if (CurrentType == "PIXELFORMATDESCRIPTOR" || CurrentType == "LAYERPLANEDESCRIPTOR" ||
|
||||
CurrentType == "GLYPHMETRICSFLOAT")
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.Tao)
|
||||
CurrentType = CurrentType.Insert(0, "Gdi.");
|
||||
else
|
||||
{
|
||||
if (CurrentType == "PIXELFORMATDESCRIPTOR")
|
||||
CurrentType = "PixelFormatDescriptor";
|
||||
else if (CurrentType == "LAYERPLANEDESCRIPTOR")
|
||||
CurrentType = "LayerPlaneDescriptor";
|
||||
else if (CurrentType == "GLYPHMETRICSFLOAT")
|
||||
CurrentType = "GlyphMetricsFloat";
|
||||
}
|
||||
}
|
||||
else if (CurrentType == "XVisualInfo")
|
||||
{
|
||||
//p.Pointer = false;
|
||||
//p.Reference = true;
|
||||
}
|
||||
else
|
||||
QualifiedType = s;
|
||||
QualifiedType = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,7 +450,7 @@ namespace Bind.Structures
|
|||
// guarantee a stable order between program executions.
|
||||
int result = this.CurrentType.CompareTo(other.CurrentType);
|
||||
if (result == 0)
|
||||
result = Pointer.CompareTo(other.Pointer);
|
||||
result = Pointer.CompareTo(other.Pointer); // Must come after array/ref, see issue [#1098]
|
||||
if (result == 0)
|
||||
result = Reference.CompareTo(other.Reference);
|
||||
if (result == 0)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Bind.Structures;
|
||||
|
||||
|
@ -47,19 +48,20 @@ namespace Bind.Wgl
|
|||
|
||||
public override void Process()
|
||||
{
|
||||
Type.Initialize(glTypemap, csTypemap);
|
||||
Enum.Initialize(enumSpec, enumSpecExt);
|
||||
Function.Initialize();
|
||||
Delegate.Initialize(glSpec, glSpecExt);
|
||||
throw new NotSupportedException();
|
||||
//Type.Initialize(glTypemap, csTypemap);
|
||||
//Enum.Initialize(enumSpec, enumSpecExt);
|
||||
//Function.Initialize();
|
||||
//Delegate.Initialize(glSpec, glSpecExt);
|
||||
|
||||
// Process enums and delegates - create wrappers.
|
||||
Trace.WriteLine("Processing specs, please wait...");
|
||||
//this.Translate();
|
||||
//// Process enums and delegates - create wrappers.
|
||||
//Trace.WriteLine("Processing specs, please wait...");
|
||||
////this.Translate();
|
||||
|
||||
WriteBindings(
|
||||
Delegate.Delegates,
|
||||
Function.Wrappers,
|
||||
Enum.GLEnums);
|
||||
//WriteBindings(
|
||||
// Delegate.Delegates,
|
||||
// Function.Wrappers,
|
||||
// Enum.GLEnums);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue