diff --git a/src/CodeGenerator/CodeGenerator.csproj b/src/CodeGenerator/CodeGenerator.csproj
index 9f05ccc..861e6a6 100644
--- a/src/CodeGenerator/CodeGenerator.csproj
+++ b/src/CodeGenerator/CodeGenerator.csproj
@@ -5,9 +5,16 @@
netcoreapp2.1
+
+
+
+
+
+ PreserveNewest
+
diff --git a/src/CodeGenerator/Program.cs b/src/CodeGenerator/Program.cs
index 18ddf86..5c87592 100644
--- a/src/CodeGenerator/Program.cs
+++ b/src/CodeGenerator/Program.cs
@@ -130,6 +130,27 @@ namespace CodeGenerator
functionsJson = JObject.Load(jr);
}
+ JObject variantsJson = null;
+ if (File.Exists(Path.Combine(AppContext.BaseDirectory, "variants.json")))
+ {
+ using (StreamReader fs = File.OpenText(Path.Combine(AppContext.BaseDirectory, "variants.json")))
+ using (JsonTextReader jr = new JsonTextReader(fs))
+ {
+ variantsJson = JObject.Load(jr);
+ }
+ }
+
+ Dictionary variants = new Dictionary();
+ foreach (var jt in variantsJson.Children())
+ {
+ JProperty jp = (JProperty)jt;
+ ParameterVariant[] methodVariants = jp.Values().Select(jv =>
+ {
+ return new ParameterVariant(jv["name"].ToString(), jv["type"].ToString(), jv["variants"].Select(s => s.ToString()).ToArray());
+ }).ToArray();
+ variants.Add(jp.Name, new MethodVariant(jp.Name, methodVariants));
+ }
+
EnumDefinition[] enums = typesJson["enums"].Select(jt =>
{
JProperty jp = (JProperty)jt;
@@ -195,11 +216,20 @@ namespace CodeGenerator
List parameters = new List();
+ // find any variants that can be applied to the parameters of this method based on the method name
+ MethodVariant methodVariants = null;
+ variants.TryGetValue(jp.Name, out methodVariants);
+
foreach (JToken p in val["argsT"])
{
string pType = p["type"].ToString();
string pName = p["name"].ToString();
- parameters.Add(new TypeReference(pName, pType, enums));
+
+ // if there are possible variants for this method then try to match them based on the parameter name and expected type
+ ParameterVariant matchingVariant = methodVariants?.Parameters.Where(pv => pv.Name == pName && pv.OriginalType == pType).FirstOrDefault() ?? null;
+ if (matchingVariant != null) matchingVariant.Used = true;
+
+ parameters.Add(new TypeReference(pName, pType, enums, matchingVariant?.VariantTypes));
}
Dictionary defaultValues = new Dictionary();
@@ -231,7 +261,7 @@ namespace CodeGenerator
isDestructor);
}).Where(od => od != null).ToArray();
- return new FunctionDefinition(name, overloads);
+ return new FunctionDefinition(name, overloads, enums);
}).OrderBy(fd => fd.Name).ToArray();
foreach (EnumDefinition ed in enums)
@@ -545,6 +575,14 @@ namespace CodeGenerator
writer.PopBlock();
writer.PopBlock();
}
+
+ foreach (var method in variants)
+ {
+ foreach (var variant in method.Value.Parameters)
+ {
+ if (!variant.Used) Console.WriteLine($"Error: Variants targetting parameter {variant.Name} with type {variant.OriginalType} could not be applied to method {method.Key}.");
+ }
+ }
}
private static bool IsStringFieldName(string name)
@@ -963,6 +1001,38 @@ namespace CodeGenerator
}
}
+ class MethodVariant
+ {
+ public string Name { get; }
+
+ public ParameterVariant[] Parameters { get; }
+
+ public MethodVariant(string name, ParameterVariant[] parameters)
+ {
+ Name = name;
+ Parameters = parameters;
+ }
+ }
+
+ class ParameterVariant
+ {
+ public string Name { get; }
+
+ public string OriginalType { get; }
+
+ public string[] VariantTypes { get; }
+
+ public bool Used { get; set; }
+
+ public ParameterVariant(string name, string originalType, string[] variantTypes)
+ {
+ Name = name;
+ OriginalType = originalType;
+ VariantTypes = variantTypes;
+ Used = false;
+ }
+ }
+
class EnumDefinition
{
private readonly Dictionary _sanitizedNames;
@@ -1049,11 +1119,18 @@ namespace CodeGenerator
public string TemplateType { get; }
public int ArraySize { get; }
public bool IsFunctionPointer { get; }
+ public string[] TypeVariants { get; }
public TypeReference(string name, string type, EnumDefinition[] enums)
- : this(name, type, null, enums) { }
+ : this(name, type, null, enums, null) { }
+
+ public TypeReference(string name, string type, EnumDefinition[] enums, string[] typeVariants)
+ : this(name, type, null, enums, typeVariants) { }
public TypeReference(string name, string type, string templateType, EnumDefinition[] enums)
+ : this(name, type, templateType, enums, null) { }
+
+ public TypeReference(string name, string type, string templateType, EnumDefinition[] enums, string[] typeVariants)
{
Name = name;
Type = type.Replace("const", string.Empty).Trim();
@@ -1082,6 +1159,8 @@ namespace CodeGenerator
}
IsFunctionPointer = Type.IndexOf('(') != -1;
+
+ TypeVariants = typeVariants;
}
private int ParseSizeString(string sizePart, EnumDefinition[] enums)
@@ -1117,6 +1196,12 @@ namespace CodeGenerator
return ret;
}
+
+ public TypeReference WithVariant(int variantIndex, EnumDefinition[] enums)
+ {
+ if (variantIndex == 0) return this;
+ else return new TypeReference(Name, TypeVariants[variantIndex - 1], TemplateType, enums);
+ }
}
class FunctionDefinition
@@ -1124,10 +1209,63 @@ namespace CodeGenerator
public string Name { get; }
public OverloadDefinition[] Overloads { get; }
- public FunctionDefinition(string name, OverloadDefinition[] overloads)
+ public FunctionDefinition(string name, OverloadDefinition[] overloads, EnumDefinition[] enums)
{
Name = name;
- Overloads = overloads;
+ Overloads = ExpandOverloadVariants(overloads, enums);
+ }
+
+ private OverloadDefinition[] ExpandOverloadVariants(OverloadDefinition[] overloads, EnumDefinition[] enums)
+ {
+ List newDefinitions = new List();
+
+ foreach (OverloadDefinition overload in overloads)
+ {
+ bool hasVariants = false;
+ int[] variantCounts = new int[overload.Parameters.Length];
+
+ for (int i = 0; i < overload.Parameters.Length; i++)
+ {
+ if (overload.Parameters[i].TypeVariants != null)
+ {
+ hasVariants = true;
+ variantCounts[i] = overload.Parameters[i].TypeVariants.Length + 1;
+ }
+ else
+ {
+ variantCounts[i] = 1;
+ }
+ }
+
+ if (hasVariants)
+ {
+ int totalVariants = variantCounts[0];
+ for (int i = 1; i < variantCounts.Length; i++) totalVariants *= variantCounts[i];
+
+ for (int i = 0; i < totalVariants; i++)
+ {
+ TypeReference[] parameters = new TypeReference[overload.Parameters.Length];
+ int div = 1;
+
+ for (int j = 0; j < parameters.Length; j++)
+ {
+ int k = (i / div) % variantCounts[j];
+
+ parameters[j] = overload.Parameters[j].WithVariant(k, enums);
+
+ if (j > 0) div *= variantCounts[j];
+ }
+
+ newDefinitions.Add(overload.WithParameters(parameters));
+ }
+ }
+ else
+ {
+ newDefinitions.Add(overload);
+ }
+ }
+
+ return newDefinitions.ToArray();
}
}
@@ -1166,6 +1304,11 @@ namespace CodeGenerator
IsConstructor = isConstructor;
IsDestructor = isDestructor;
}
+
+ public OverloadDefinition WithParameters(TypeReference[] parameters)
+ {
+ return new OverloadDefinition(ExportedName, FriendlyName, parameters, DefaultValues, ReturnType, StructName, Comment, IsConstructor, IsDestructor);
+ }
}
class MarshalledParameter
diff --git a/src/CodeGenerator/variants.json b/src/CodeGenerator/variants.json
new file mode 100644
index 0000000..8b94900
--- /dev/null
+++ b/src/CodeGenerator/variants.json
@@ -0,0 +1,16 @@
+{
+ "ImFontAtlas_GetTexDataAsAlpha8": [
+ {
+ "name": "out_pixels",
+ "type": "unsigned char**",
+ "variants": [ "IntPtr*" ]
+ }
+ ],
+ "ImFontAtlas_GetTexDataAsRGBA32": [
+ {
+ "name": "out_pixels",
+ "type": "unsigned char**",
+ "variants": [ "IntPtr*" ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/ImGui.NET.SampleProgram/ImGuiController.cs b/src/ImGui.NET.SampleProgram/ImGuiController.cs
index 64d6ef9..ca40da7 100644
--- a/src/ImGui.NET.SampleProgram/ImGuiController.cs
+++ b/src/ImGui.NET.SampleProgram/ImGuiController.cs
@@ -244,11 +244,11 @@ namespace ImGuiNET
///
/// Recreates the device texture used to render text.
///
- public unsafe void RecreateFontDeviceTexture(GraphicsDevice gd)
+ public void RecreateFontDeviceTexture(GraphicsDevice gd)
{
ImGuiIOPtr io = ImGui.GetIO();
// Build
- byte* pixels;
+ IntPtr pixels;
int width, height, bytesPerPixel;
io.Fonts.GetTexDataAsRGBA32(out pixels, out width, out height, out bytesPerPixel);
// Store our identifier
@@ -264,7 +264,7 @@ namespace ImGuiNET
_fontTexture.Name = "ImGui.NET Font Texture";
gd.UpdateTexture(
_fontTexture,
- (IntPtr)pixels,
+ pixels,
(uint)(bytesPerPixel * width * height),
0,
0,
diff --git a/src/ImGui.NET/Generated/ImFontAtlas.gen.cs b/src/ImGui.NET/Generated/ImFontAtlas.gen.cs
index d398228..70a2c5d 100644
--- a/src/ImGui.NET/Generated/ImFontAtlas.gen.cs
+++ b/src/ImGui.NET/Generated/ImFontAtlas.gen.cs
@@ -434,6 +434,36 @@ namespace ImGuiNET
}
}
}
+ public void GetTexDataAsAlpha8(out IntPtr out_pixels, out int out_width, out int out_height)
+ {
+ int* out_bytes_per_pixel = null;
+ fixed (IntPtr* native_out_pixels = &out_pixels)
+ {
+ fixed (int* native_out_width = &out_width)
+ {
+ fixed (int* native_out_height = &out_height)
+ {
+ ImGuiNative.ImFontAtlas_GetTexDataAsAlpha8(NativePtr, native_out_pixels, native_out_width, native_out_height, out_bytes_per_pixel);
+ }
+ }
+ }
+ }
+ public void GetTexDataAsAlpha8(out IntPtr out_pixels, out int out_width, out int out_height, out int out_bytes_per_pixel)
+ {
+ fixed (IntPtr* native_out_pixels = &out_pixels)
+ {
+ fixed (int* native_out_width = &out_width)
+ {
+ fixed (int* native_out_height = &out_height)
+ {
+ fixed (int* native_out_bytes_per_pixel = &out_bytes_per_pixel)
+ {
+ ImGuiNative.ImFontAtlas_GetTexDataAsAlpha8(NativePtr, native_out_pixels, native_out_width, native_out_height, native_out_bytes_per_pixel);
+ }
+ }
+ }
+ }
+ }
public void GetTexDataAsRGBA32(out byte* out_pixels, out int out_width, out int out_height)
{
int* out_bytes_per_pixel = null;
@@ -464,6 +494,36 @@ namespace ImGuiNET
}
}
}
+ public void GetTexDataAsRGBA32(out IntPtr out_pixels, out int out_width, out int out_height)
+ {
+ int* out_bytes_per_pixel = null;
+ fixed (IntPtr* native_out_pixels = &out_pixels)
+ {
+ fixed (int* native_out_width = &out_width)
+ {
+ fixed (int* native_out_height = &out_height)
+ {
+ ImGuiNative.ImFontAtlas_GetTexDataAsRGBA32(NativePtr, native_out_pixels, native_out_width, native_out_height, out_bytes_per_pixel);
+ }
+ }
+ }
+ }
+ public void GetTexDataAsRGBA32(out IntPtr out_pixels, out int out_width, out int out_height, out int out_bytes_per_pixel)
+ {
+ fixed (IntPtr* native_out_pixels = &out_pixels)
+ {
+ fixed (int* native_out_width = &out_width)
+ {
+ fixed (int* native_out_height = &out_height)
+ {
+ fixed (int* native_out_bytes_per_pixel = &out_bytes_per_pixel)
+ {
+ ImGuiNative.ImFontAtlas_GetTexDataAsRGBA32(NativePtr, native_out_pixels, native_out_width, native_out_height, native_out_bytes_per_pixel);
+ }
+ }
+ }
+ }
+ }
public bool IsBuilt()
{
byte ret = ImGuiNative.ImFontAtlas_IsBuilt(NativePtr);
diff --git a/src/ImGui.NET/Generated/ImGuiNative.gen.cs b/src/ImGui.NET/Generated/ImGuiNative.gen.cs
index 37bf3da..39bc715 100644
--- a/src/ImGui.NET/Generated/ImGuiNative.gen.cs
+++ b/src/ImGui.NET/Generated/ImGuiNative.gen.cs
@@ -909,8 +909,12 @@ namespace ImGuiNET
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
public static extern void ImFontAtlas_GetTexDataAsAlpha8(ImFontAtlas* self, byte** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel);
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ImFontAtlas_GetTexDataAsAlpha8(ImFontAtlas* self, IntPtr* out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel);
+ [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
public static extern void ImFontAtlas_GetTexDataAsRGBA32(ImFontAtlas* self, byte** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel);
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ImFontAtlas_GetTexDataAsRGBA32(ImFontAtlas* self, IntPtr* out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel);
+ [DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
public static extern ImFontAtlas* ImFontAtlas_ImFontAtlas();
[DllImport("cimgui", CallingConvention = CallingConvention.Cdecl)]
public static extern byte ImFontAtlas_IsBuilt(ImFontAtlas* self);