in utils/SkiaSharpGenerator/Generate/Generator.cs [438:527]
private void WriteFunctions(TextWriter writer)
{
Log?.LogVerbose(" Writing p/invokes...");
var functionGroups = compilation.Functions
.Where(f => IncludeNamespace(f.Name))
.OrderBy(f => f.Name)
.GroupBy(f => f.Span.Start.File.ToLower().Replace("\\", "/"))
.OrderBy(g => Path.GetDirectoryName(g.Key) + "/" + Path.GetFileName(g.Key));
foreach (var group in functionGroups)
{
var fullPath = Path.GetFullPath(group.Key).ToLower();
if (excludedFiles.Any(e => Path.GetFullPath(e).ToLower() == fullPath))
{
Log?.LogVerbose($" Skipping file '{group.Key}' because it was in the exclude list.");
continue;
}
writer.WriteLine($"\t\t#region {Path.GetFileName(group.Key)}");
foreach (var function in group)
{
Log?.LogVerbose($" {function.Name}");
var name = function.Name;
functionMappings.TryGetValue(name, out var funcMap);
var skipFunction = false;
var paramsList = new List<string>();
var paramNamesList = new List<string>();
for (var i = 0; i < function.Parameters.Count; i++)
{
var p = function.Parameters[i];
var n = string.IsNullOrEmpty(p.Name) ? $"param{i}" : p.Name;
n = SafeName(n);
var t = GetType(p.Type);
var cppT = GetCppType(p.Type);
if (excludedTypes.Contains(cppT) == true)
{
Log?.LogVerbose($" Skipping function '{function.Name}' because parameter '{cppT}' was in the exclude list.");
skipFunction = true;
break;
}
if (t == "Boolean" || cppT == "bool")
t = $"[MarshalAs (UnmanagedType.I1)] bool";
if (funcMap != null && funcMap.Parameters.TryGetValue(i.ToString(), out var newT))
t = newT;
paramsList.Add($"{t} {n}");
paramNamesList.Add(n);
}
if (skipFunction)
continue;
var returnType = GetType(function.ReturnType);
var retAttr = "";
if (funcMap != null && funcMap.Parameters.TryGetValue("-1", out var newR))
{
returnType = newR;
}
else if (returnType == "Boolean" || GetCppType(function.ReturnType) == "bool")
{
returnType = "bool";
retAttr = $"[return: MarshalAs (UnmanagedType.I1)]";
}
writer.WriteLine();
writer.WriteLine($"\t\t// {function}");
writer.WriteLine($"\t\t#if !USE_DELEGATES");
writer.WriteLine($"\t\t[DllImport ({config.DllName}, CallingConvention = CallingConvention.Cdecl)]");
if (!string.IsNullOrEmpty(retAttr))
writer.WriteLine($"\t\t{retAttr}");
writer.WriteLine($"\t\tinternal static extern {returnType} {name} ({string.Join(", ", paramsList)});");
writer.WriteLine($"\t\t#else");
writer.WriteLine($"\t\tprivate partial class Delegates {{");
writer.WriteLine($"\t\t\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]");
if (!string.IsNullOrEmpty(retAttr))
writer.WriteLine($"\t\t\t{retAttr}");
writer.WriteLine($"\t\t\tinternal delegate {returnType} {name} ({string.Join(", ", paramsList)});");
writer.WriteLine($"\t\t}}");
writer.WriteLine($"\t\tprivate static Delegates.{name} {name}_delegate;");
writer.WriteLine($"\t\tinternal static {returnType} {name} ({string.Join(", ", paramsList)}) =>");
writer.WriteLine($"\t\t\t({name}_delegate ??= GetSymbol<Delegates.{name}> (\"{name}\")).Invoke ({string.Join(", ", paramNamesList)});");
writer.WriteLine($"\t\t#endif");
}
writer.WriteLine();
writer.WriteLine($"\t\t#endregion");
writer.WriteLine();
}
}