Added support for lazy binding loading

This commit is contained in:
Stefanos A 2013-11-22 20:06:49 +01:00
parent 5d0e7a4acf
commit 0fea0a19b7

View file

@ -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)