mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-11 05:35:35 +00:00
Added support for lazy binding loading
This commit is contained in:
parent
5d0e7a4acf
commit
0fea0a19b7
|
@ -202,28 +202,6 @@ namespace Bind
|
||||||
sw.WriteLine("{");
|
sw.WriteLine("{");
|
||||||
sw.Indent();
|
sw.Indent();
|
||||||
|
|
||||||
// Write constructor to initialize entry points
|
|
||||||
sw.WriteLine("public {0}()", Settings.OutputClass);
|
|
||||||
sw.WriteLine("{");
|
|
||||||
sw.Indent();
|
|
||||||
sw.WriteLine("IGraphicsContextInternal context = GraphicsContext.CurrentContext as IGraphicsContextInternal;");
|
|
||||||
sw.WriteLine("if (context == null) throw new GraphicsContextMissingException();");
|
|
||||||
sw.WriteLine();
|
|
||||||
|
|
||||||
foreach (var overloads in delegates.Values)
|
|
||||||
{
|
|
||||||
var d = overloads.First();
|
|
||||||
sw.WriteLine("{0}{1}{2}{3} = ({0}{1}{3})GetExtensionDelegate(\"{2}{3}\", typeof({0}{1}{3}));",
|
|
||||||
Settings.DelegatesClass,
|
|
||||||
Settings.NamespaceSeparator,
|
|
||||||
Settings.FunctionPrefix,
|
|
||||||
d.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
sw.Unindent();
|
|
||||||
sw.WriteLine("}");
|
|
||||||
sw.WriteLine();
|
|
||||||
|
|
||||||
// Write internal class to hold entry points
|
// Write internal class to hold entry points
|
||||||
sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass);
|
sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass);
|
||||||
sw.WriteLine("{");
|
sw.WriteLine("{");
|
||||||
|
@ -238,7 +216,7 @@ namespace Bind
|
||||||
|
|
||||||
sw.WriteLine("[SuppressUnmanagedCodeSecurity]");
|
sw.WriteLine("[SuppressUnmanagedCodeSecurity]");
|
||||||
sw.WriteLine("internal {0};", GetDeclarationString(d, true));
|
sw.WriteLine("internal {0};", GetDeclarationString(d, true));
|
||||||
sw.WriteLine("internal {0}static {2} {1}{2};", // = null
|
sw.WriteLine("internal {0}static {2} {1}{2} = Load_{2};",
|
||||||
d.Unsafe ? "unsafe " : "",
|
d.Unsafe ? "unsafe " : "",
|
||||||
Settings.FunctionPrefix,
|
Settings.FunctionPrefix,
|
||||||
d.Name);
|
d.Name);
|
||||||
|
@ -247,6 +225,28 @@ namespace Bind
|
||||||
sw.Unindent();
|
sw.Unindent();
|
||||||
sw.WriteLine("}");
|
sw.WriteLine("}");
|
||||||
|
|
||||||
|
foreach (var d in delegates.Values.Select(d => d.First()))
|
||||||
|
{
|
||||||
|
var load_d = new Delegate(d);
|
||||||
|
load_d.Name = "Load_" + load_d.Name;
|
||||||
|
|
||||||
|
sw.WriteLine("internal static {0}", GetDeclarationString(load_d, false));
|
||||||
|
sw.WriteLine("{");
|
||||||
|
sw.Indent();
|
||||||
|
|
||||||
|
sw.WriteLine("{2}{3}{0}{1} = ({2}{3}{1})GetExtensionDelegateStatic(\"{0}{1}\", typeof({2}{3}{1}));",
|
||||||
|
Settings.FunctionPrefix,
|
||||||
|
d.Name,
|
||||||
|
Settings.DelegatesClass,
|
||||||
|
Settings.NamespaceSeparator);
|
||||||
|
sw.WriteLine("{0}{1};",
|
||||||
|
d.ReturnType.CurrentType != "void" ? "return " : "",
|
||||||
|
GetInvocationString(d, false));
|
||||||
|
|
||||||
|
sw.Unindent();
|
||||||
|
sw.WriteLine("}");
|
||||||
|
}
|
||||||
|
|
||||||
sw.Unindent();
|
sw.Unindent();
|
||||||
sw.WriteLine("}");
|
sw.WriteLine("}");
|
||||||
}
|
}
|
||||||
|
@ -789,15 +789,16 @@ namespace Bind
|
||||||
// Note: We cannot generate a callstring using WrappedDelegate directly, as its parameters will
|
// 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
|
// typically be different than the parameters of the wrapper. We need to modify the parameters
|
||||||
// of the wrapper directly.
|
// of the wrapper directly.
|
||||||
|
var wrapped = new Delegate(f.WrappedDelegate);
|
||||||
if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0)
|
if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0)
|
||||||
{
|
{
|
||||||
int parameter_index = -1; // Used for comparing wrapper parameters with delegate parameters
|
int parameter_index = -1; // Used for comparing wrapper parameters with delegate parameters
|
||||||
foreach (Parameter p in f.Parameters)
|
foreach (Parameter p in f.Parameters)
|
||||||
{
|
{
|
||||||
parameter_index++;
|
parameter_index++;
|
||||||
if (IsEnum(p.Name, enums) && p.QualifiedType != f.WrappedDelegate.Parameters[parameter_index].QualifiedType)
|
if (IsEnum(p.Name, enums) && p.QualifiedType != wrapped.Parameters[parameter_index].QualifiedType)
|
||||||
{
|
{
|
||||||
p.QualifiedType = f.WrappedDelegate.Parameters[parameter_index].QualifiedType;
|
p.QualifiedType = wrapped.Parameters[parameter_index].QualifiedType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -805,11 +806,11 @@ namespace Bind
|
||||||
if (assign_statements.Count > 0)
|
if (assign_statements.Count > 0)
|
||||||
{
|
{
|
||||||
// Call function
|
// Call function
|
||||||
var callstring = GetInvocationString(f);
|
var callstring = GetInvocationString(f, true);
|
||||||
if (func.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType))
|
if (func.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType))
|
||||||
{
|
{
|
||||||
// foo(int id) { foo(1, ref id) }
|
// foo(int id) { foo(1, ref id) }
|
||||||
callstring = GetInvocationString(f.WrappedDelegate);
|
callstring = GetInvocationString(wrapped, true);
|
||||||
f.Body.Add(String.Format("{0}{1};",
|
f.Body.Add(String.Format("{0}{1};",
|
||||||
f.ReturnType.CurrentType.ToLower().Contains("void") ? String.Empty : "return ",
|
f.ReturnType.CurrentType.ToLower().Contains("void") ? String.Empty : "return ",
|
||||||
callstring));
|
callstring));
|
||||||
|
@ -822,8 +823,8 @@ namespace Bind
|
||||||
func.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType)
|
func.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType)
|
||||||
{
|
{
|
||||||
// int foo() { int value; foo(1, &value); retval = value }
|
// int foo() { int value; foo(1, &value); retval = value }
|
||||||
callstring = GetInvocationString(f.WrappedDelegate);
|
callstring = GetInvocationString(wrapped, true);
|
||||||
var p = f.WrappedDelegate.Parameters.Last();
|
var p = wrapped.Parameters.Last();
|
||||||
f.Body.Add(String.Format("{0};", callstring));
|
f.Body.Add(String.Format("{0};", callstring));
|
||||||
f.Body.Add(String.Format(
|
f.Body.Add(String.Format(
|
||||||
"retval = {0}{1};",
|
"retval = {0}{1};",
|
||||||
|
@ -853,11 +854,11 @@ namespace Bind
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Call function and return
|
// Call function and return
|
||||||
var callstring = GetInvocationString(f);
|
var callstring = GetInvocationString(f, true);
|
||||||
if (func.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType))
|
if (func.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType))
|
||||||
{
|
{
|
||||||
// int foo(int id) { return foo(1, ref id) }
|
// int foo(int id) { return foo(1, ref id) }
|
||||||
callstring = GetInvocationString(f.WrappedDelegate);
|
callstring = GetInvocationString(wrapped, true);
|
||||||
f.Body.Add(String.Format("{0}{1};",
|
f.Body.Add(String.Format("{0}{1};",
|
||||||
f.ReturnType.CurrentType.ToLower().Contains("void") ? String.Empty : "return ",
|
f.ReturnType.CurrentType.ToLower().Contains("void") ? String.Empty : "return ",
|
||||||
callstring));
|
callstring));
|
||||||
|
@ -870,7 +871,7 @@ namespace Bind
|
||||||
func.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType)
|
func.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType)
|
||||||
{
|
{
|
||||||
// int foo() { int retval; foo(1, &retval); return retval }
|
// int foo() { int retval; foo(1, &retval); return retval }
|
||||||
callstring = GetInvocationString(f.WrappedDelegate);
|
callstring = GetInvocationString(wrapped, true);
|
||||||
f.Body.Add(String.Format("{0};", callstring));
|
f.Body.Add(String.Format("{0};", callstring));
|
||||||
f.Body.Add(String.Format("return retval;"));
|
f.Body.Add(String.Format("return retval;"));
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1112,7 @@ namespace Bind
|
||||||
array_levels[type.Array]);
|
array_levels[type.Array]);
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetInvocationString(Delegate d)
|
string GetInvocationString(Delegate d, bool respect_wrappers)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
@ -1119,12 +1120,12 @@ namespace Bind
|
||||||
sb.Append(Settings.NamespaceSeparator);
|
sb.Append(Settings.NamespaceSeparator);
|
||||||
sb.Append(Settings.FunctionPrefix);
|
sb.Append(Settings.FunctionPrefix);
|
||||||
sb.Append(d.Name);
|
sb.Append(d.Name);
|
||||||
sb.Append(GetInvocationString(d.Parameters));
|
sb.Append(GetInvocationString(d.Parameters, respect_wrappers));
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetInvocationString(ParameterCollection parameters)
|
string GetInvocationString(ParameterCollection parameters, bool respect_wrappers)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
@ -1168,30 +1169,37 @@ namespace Bind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (p.WrapperType)
|
if (respect_wrappers)
|
||||||
{
|
{
|
||||||
case WrapperTypes.GenericParameter:
|
switch (p.WrapperType)
|
||||||
if (p.Generic)
|
{
|
||||||
{
|
case WrapperTypes.GenericParameter:
|
||||||
sb.Append("(IntPtr)");
|
if (p.Generic)
|
||||||
sb.Append(p.Name);
|
{
|
||||||
sb.Append("_ptr.AddrOfPinnedObject()");
|
sb.Append("(IntPtr)");
|
||||||
}
|
sb.Append(p.Name);
|
||||||
else
|
sb.Append("_ptr.AddrOfPinnedObject()");
|
||||||
{
|
}
|
||||||
sb.Append(p.Name);
|
else
|
||||||
}
|
{
|
||||||
break;
|
sb.Append(p.Name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WrapperTypes.ArrayParameter:
|
case WrapperTypes.ArrayParameter:
|
||||||
case WrapperTypes.ReferenceParameter:
|
case WrapperTypes.ReferenceParameter:
|
||||||
sb.Append(p.Name);
|
sb.Append(p.Name);
|
||||||
sb.Append("_ptr");
|
sb.Append("_ptr");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sb.Append(p.Name);
|
sb.Append(p.Name);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(p.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.Unchecked)
|
if (p.Unchecked)
|
||||||
|
|
Loading…
Reference in a new issue