Skip to content

Commit 02a838f

Browse files
committed
Preparing code generator for ImPlot, ImNodes and ImGuizmo code generation
1 parent 9b74ee4 commit 02a838f

File tree

7 files changed

+123
-37
lines changed

7 files changed

+123
-37
lines changed

src/CodeGenerator/CodeGenerator.csproj

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,24 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<Content Include="structs_and_enums.json" CopyToOutputDirectory="PreserveNewest" />
10-
<Content Include="definitions.json" CopyToOutputDirectory="PreserveNewest" />
11-
<Content Include="variants.json" CopyToOutputDirectory="PreserveNewest" />
9+
<Content Include="definitions\cimgui\structs_and_enums.json" CopyToOutputDirectory="PreserveNewest" />
10+
<Content Include="definitions\cimgui\definitions.json" CopyToOutputDirectory="PreserveNewest" />
11+
<Content Include="definitions\cimgui\variants.json" CopyToOutputDirectory="PreserveNewest" />
12+
13+
<Content Include="definitions\cimplot\structs_and_enums.json" CopyToOutputDirectory="PreserveNewest" />
14+
<Content Include="definitions\cimplot\definitions.json" CopyToOutputDirectory="PreserveNewest" />
15+
<Content Include="definitions\cimplot\variants.json" CopyToOutputDirectory="PreserveNewest" />
16+
17+
<Content Include="definitions\cimnodes\structs_and_enums.json" CopyToOutputDirectory="PreserveNewest" />
18+
<Content Include="definitions\cimnodes\definitions.json" CopyToOutputDirectory="PreserveNewest" />
19+
<Content Include="definitions\cimnodes\variants.json" CopyToOutputDirectory="PreserveNewest" />
20+
21+
<Content Include="definitions\cimguizmo\structs_and_enums.json" CopyToOutputDirectory="PreserveNewest" />
22+
<Content Include="definitions\cimguizmo\definitions.json" CopyToOutputDirectory="PreserveNewest" />
23+
<Content Include="definitions\cimguizmo\variants.json" CopyToOutputDirectory="PreserveNewest" />
1224
</ItemGroup>
1325

1426
<ItemGroup>
1527
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
1628
</ItemGroup>
17-
1829
</Project>

src/CodeGenerator/ImguiDefinitions.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void LoadFrom(string directory)
4141
JObject variantsJson = null;
4242
if (File.Exists(Path.Combine(directory, "variants.json")))
4343
{
44-
using (StreamReader fs = File.OpenText(Path.Combine(AppContext.BaseDirectory, "variants.json")))
44+
using (StreamReader fs = File.OpenText(Path.Combine(directory, "variants.json")))
4545
using (JsonTextReader jr = new JsonTextReader(fs))
4646
{
4747
variantsJson = JObject.Load(jr);
@@ -275,6 +275,9 @@ private string SanitizeMemberName(string memberName)
275275
ret = ret.Substring(0, ret.Length - 1);
276276
}
277277

278+
if (Char.IsDigit(ret.First()))
279+
ret = "_" + ret;
280+
278281
return ret;
279282
}
280283
}
@@ -368,7 +371,7 @@ public TypeReference(string name, string type, int asize, string templateType, E
368371

369372
TypeVariants = typeVariants;
370373

371-
IsEnum = enums.Any(t => t.Name == type || t.FriendlyName == type);
374+
IsEnum = enums.Any(t => t.Name == type || t.FriendlyName == type || TypeInfo.WellKnownEnums.Contains(type));
372375
}
373376

374377
private int ParseSizeString(string sizePart, EnumDefinition[] enums)

src/CodeGenerator/Program.cs

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,55 @@ static void Main(string[] args)
2424
{
2525
outputPath = AppContext.BaseDirectory;
2626
}
27+
28+
string libraryName;
29+
if (args.Length > 1)
30+
{
31+
libraryName = args[1];
32+
}
33+
else
34+
{
35+
libraryName = "cimgui";
36+
}
37+
38+
string projectNamespace = libraryName switch
39+
{
40+
"cimgui" => "ImGuiNET",
41+
"cimplot" => "ImGuiNET",
42+
"cimnodes" => "ImGuiNET",
43+
"cimguizmo" => "ImGuiNET",
44+
_ => throw new NotImplementedException()
45+
};
46+
47+
string classPrefix = libraryName switch
48+
{
49+
"cimgui" => "ImGui",
50+
"cimplot" => "ImPlot",
51+
"cimnodes" => "ImNodes",
52+
"cimguizmo" => "ImGuizmo",
53+
_ => throw new NotImplementedException()
54+
};
55+
56+
string dllName = libraryName switch
57+
{
58+
"cimgui" => "cimgui",
59+
"cimplot" => "cimgui",
60+
"cimnodes" => "cimgui",
61+
"cimguizmo" => "cimgui",
62+
_ => throw new NotImplementedException()
63+
};
2764

65+
string definitionsPath = Path.Combine(AppContext.BaseDirectory, "definitions", libraryName);
2866
var defs = new ImguiDefinitions();
29-
defs.LoadFrom(AppContext.BaseDirectory);
30-
67+
defs.LoadFrom(definitionsPath);
68+
3169
Console.WriteLine($"Outputting generated code files to {outputPath}.");
3270

3371
foreach (EnumDefinition ed in defs.Enums)
3472
{
3573
using (CSharpCodeWriter writer = new CSharpCodeWriter(Path.Combine(outputPath, ed.FriendlyName + ".gen.cs")))
3674
{
37-
writer.PushBlock("namespace ImGuiNET");
75+
writer.PushBlock($"namespace {projectNamespace}");
3876
if (ed.FriendlyName.Contains("Flags"))
3977
{
4078
writer.WriteLine("[System.Flags]");
@@ -62,7 +100,7 @@ static void Main(string[] args)
62100
writer.Using("System.Runtime.CompilerServices");
63101
writer.Using("System.Text");
64102
writer.WriteLine(string.Empty);
65-
writer.PushBlock("namespace ImGuiNET");
103+
writer.PushBlock($"namespace {projectNamespace}");
66104

67105
writer.PushBlock($"public unsafe partial struct {td.Name}");
68106
foreach (TypeReference field in td.Fields)
@@ -209,7 +247,7 @@ static void Main(string[] args)
209247
{
210248
defaults.Add(orderedDefaults[j].Key, orderedDefaults[j].Value);
211249
}
212-
EmitOverload(writer, overload, defaults, "NativePtr");
250+
EmitOverload(writer, overload, defaults, "NativePtr", classPrefix);
213251
}
214252
}
215253
}
@@ -219,14 +257,14 @@ static void Main(string[] args)
219257
}
220258
}
221259

222-
using (CSharpCodeWriter writer = new CSharpCodeWriter(Path.Combine(outputPath, "ImGuiNative.gen.cs")))
260+
using (CSharpCodeWriter writer = new CSharpCodeWriter(Path.Combine(outputPath, $"{classPrefix}Native.gen.cs")))
223261
{
224262
writer.Using("System");
225263
writer.Using("System.Numerics");
226264
writer.Using("System.Runtime.InteropServices");
227265
writer.WriteLine(string.Empty);
228-
writer.PushBlock("namespace ImGuiNET");
229-
writer.PushBlock("public static unsafe partial class ImGuiNative");
266+
writer.PushBlock($"namespace {projectNamespace}");
267+
writer.PushBlock($"public static unsafe partial class {classPrefix}Native");
230268
foreach (FunctionDefinition fd in defs.Functions)
231269
{
232270
foreach (OverloadDefinition overload in fd.Overloads)
@@ -273,12 +311,12 @@ static void Main(string[] args)
273311

274312
if (isUdtVariant)
275313
{
276-
writer.WriteLine($"[DllImport(\"cimgui\", CallingConvention = CallingConvention.Cdecl, EntryPoint = \"{exportedName}\")]");
314+
writer.WriteLine($"[DllImport(\"{dllName}\", CallingConvention = CallingConvention.Cdecl, EntryPoint = \"{exportedName}\")]");
277315

278316
}
279317
else
280318
{
281-
writer.WriteLine("[DllImport(\"cimgui\", CallingConvention = CallingConvention.Cdecl)]");
319+
writer.WriteLine($"[DllImport(\"{dllName}\", CallingConvention = CallingConvention.Cdecl)]");
282320
}
283321
writer.WriteLine($"public static extern {ret} {methodName}({parameters});");
284322
}
@@ -287,15 +325,15 @@ static void Main(string[] args)
287325
writer.PopBlock();
288326
}
289327

290-
using (CSharpCodeWriter writer = new CSharpCodeWriter(Path.Combine(outputPath, "ImGui.gen.cs")))
328+
using (CSharpCodeWriter writer = new CSharpCodeWriter(Path.Combine(outputPath, $"{classPrefix}.gen.cs")))
291329
{
292330
writer.Using("System");
293331
writer.Using("System.Numerics");
294332
writer.Using("System.Runtime.InteropServices");
295333
writer.Using("System.Text");
296334
writer.WriteLine(string.Empty);
297-
writer.PushBlock("namespace ImGuiNET");
298-
writer.PushBlock("public static unsafe partial class ImGui");
335+
writer.PushBlock($"namespace {projectNamespace}");
336+
writer.PushBlock($"public static unsafe partial class {classPrefix}");
299337
foreach (FunctionDefinition fd in defs.Functions)
300338
{
301339
if (TypeInfo.SkippedFunctions.Contains(fd.Name)) { continue; }
@@ -336,7 +374,7 @@ static void Main(string[] args)
336374
{
337375
defaults.Add(orderedDefaults[j].Key, orderedDefaults[j].Value);
338376
}
339-
EmitOverload(writer, overload, defaults, null);
377+
EmitOverload(writer, overload, defaults, null, classPrefix);
340378
}
341379
}
342380
}
@@ -381,7 +419,8 @@ private static void EmitOverload(
381419
CSharpCodeWriter writer,
382420
OverloadDefinition overload,
383421
Dictionary<string, string> defaultValues,
384-
string selfName)
422+
string selfName,
423+
string classPrefix)
385424
{
386425
if (overload.Parameters.Where(tr => tr.Name.EndsWith("_begin") || tr.Name.EndsWith("_end"))
387426
.Any(tr => !defaultValues.ContainsKey(tr.Name)))
@@ -481,6 +520,15 @@ private static void EmitOverload(
481520
postCallLines.Add($"}}");
482521
}
483522
}
523+
else if (defaultValues.TryGetValue(tr.Name, out string defaultVal))
524+
{
525+
if (!CorrectDefaultValue(defaultVal, tr, out string correctedDefault))
526+
{
527+
correctedDefault = defaultVal;
528+
}
529+
marshalledParameters[i] = new MarshalledParameter(nativeTypeName, false, correctedIdentifier, true);
530+
preCallLines.Add($"{nativeTypeName} {correctedIdentifier} = {correctedDefault};");
531+
}
484532
else if (tr.Type == "char* []")
485533
{
486534
string nativeArgName = "native_" + tr.Name;
@@ -518,15 +566,6 @@ private static void EmitOverload(
518566
preCallLines.Add($" offset += {correctedIdentifier}_byteCounts[i] + 1;");
519567
preCallLines.Add("}");
520568
}
521-
else if (defaultValues.TryGetValue(tr.Name, out string defaultVal))
522-
{
523-
if (!CorrectDefaultValue(defaultVal, tr, out string correctedDefault))
524-
{
525-
correctedDefault = defaultVal;
526-
}
527-
marshalledParameters[i] = new MarshalledParameter(nativeTypeName, false, correctedIdentifier, true);
528-
preCallLines.Add($"{nativeTypeName} {correctedIdentifier} = {correctedDefault};");
529-
}
530569
else if (tr.Type == "bool")
531570
{
532571
string nativeArgName = "native_" + tr.Name;
@@ -557,7 +596,7 @@ private static void EmitOverload(
557596
marshalledParameters[i] = new MarshalledParameter(wrappedParamType, false, nativeArgName, false);
558597
preCallLines.Add($"{tr.Type} {nativeArgName} = {correctedIdentifier}.NativePtr;");
559598
}
560-
else if ((tr.Type.EndsWith("*") || tr.Type.Contains("[") || tr.Type.EndsWith("&")) && tr.Type != "void*" && tr.Type != "ImGuiContext*")
599+
else if ((tr.Type.EndsWith("*") || tr.Type.Contains("[") || tr.Type.EndsWith("&")) && tr.Type != "void*" && tr.Type != "ImGuiContext*" && tr.Type != "ImPlotContext*"&& tr.Type != "EditorContext*")
561600
{
562601
string nonPtrType;
563602
if (tr.Type.Contains("["))
@@ -634,7 +673,7 @@ private static void EmitOverload(
634673
targetName = targetName.Substring(0, targetName.IndexOf("_nonUDT"));
635674
}
636675

637-
writer.WriteLine($"{ret}ImGuiNative.{targetName}({nativeInvocationStr});");
676+
writer.WriteLine($"{ret}{classPrefix}Native.{targetName}({nativeInvocationStr});");
638677

639678
foreach (string line in postCallLines)
640679
{
@@ -736,7 +775,7 @@ private static bool GetWrappedType(string nativeType, out string wrappedType)
736775

737776
private static bool CorrectDefaultValue(string defaultVal, TypeReference tr, out string correctedDefault)
738777
{
739-
if (tr.Type == "ImGuiContext*")
778+
if (tr.Type == "ImGuiContext*" || tr.Type == "ImPlotContext*" || tr.Type == "EditorContext*")
740779
{
741780
correctedDefault = "IntPtr.Zero";
742781
return true;
@@ -754,7 +793,10 @@ private static bool CorrectDefaultValue(string defaultVal, TypeReference tr, out
754793

755794
if (tr.IsEnum)
756795
{
757-
correctedDefault = $"({tr.Type}){defaultVal}";
796+
if (defaultVal.StartsWith("-"))
797+
correctedDefault = $"({tr.Type})({defaultVal})";
798+
else
799+
correctedDefault = $"({tr.Type}){defaultVal}";
758800
return true;
759801
}
760802

src/CodeGenerator/TypeInfo.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ public class TypeInfo
1414
{ "ImFileHandle", "IntPtr" },
1515
{ "ImU8", "byte" },
1616
{ "ImS8", "sbyte" },
17+
{ "ImU16", "ushort" },
18+
{ "ImS16", "short" },
19+
{ "ImU32", "uint" },
20+
{ "ImS32", "int" },
1721
{ "ImU64", "ulong" },
22+
{ "ImS64", "long" },
1823
{ "unsigned short", "ushort" },
1924
{ "unsigned int", "uint" },
2025
{ "ImVec2", "Vector2" },
@@ -29,10 +34,11 @@ public class TypeInfo
2934
{ "ImDrawIdx", "ushort" },
3035
{ "ImDrawListSharedData", "IntPtr" },
3136
{ "ImDrawListSharedData*", "IntPtr" },
32-
{ "ImU32", "uint" },
3337
{ "ImDrawCallback", "IntPtr" },
3438
{ "size_t", "uint" },
3539
{ "ImGuiContext*", "IntPtr" },
40+
{ "ImPlotContext*", "IntPtr" },
41+
{ "EditorContext*", "IntPtr" },
3642
{ "float[2]", "Vector2*" },
3743
{ "float[3]", "Vector3*" },
3844
{ "float[4]", "Vector4*" },
@@ -44,7 +50,12 @@ public class TypeInfo
4450
{ "char* []", "byte**" },
4551
{ "unsigned char[256]", "byte*"},
4652
};
47-
53+
54+
public static readonly List<string> WellKnownEnums = new List<string>()
55+
{
56+
"ImGuiMouseButton"
57+
};
58+
4859
public static readonly Dictionary<string, string> WellKnownFieldReplacements = new Dictionary<string, string>()
4960
{
5061
{ "bool", "bool" }, // Force bool to remain as bool in type-safe wrappers.
@@ -62,16 +73,35 @@ public class TypeInfo
6273
{
6374
{ "((void *)0)", "null" },
6475
{ "((void*)0)", "null" },
76+
{ "NULL", "null"},
77+
{ "nullptr", "null"},
6578
{ "ImVec2(0,0)", "new Vector2()" },
6679
{ "ImVec2(-1,0)", "new Vector2(-1, 0)" },
6780
{ "ImVec2(1,0)", "new Vector2(1, 0)" },
6881
{ "ImVec2(1,1)", "new Vector2(1, 1)" },
6982
{ "ImVec2(0,1)", "new Vector2(0, 1)" },
7083
{ "ImVec4(0,0,0,0)", "new Vector4()" },
7184
{ "ImVec4(1,1,1,1)", "new Vector4(1, 1, 1, 1)" },
85+
{ "ImVec4(0,0,0,-1)", "new Vector4(0, 0, 0, -1)" },
86+
{ "ImPlotPoint(0,0)", "new ImPlotPoint { x = 0, y = 0 }" },
87+
{ "ImPlotPoint(1,1)", "new ImPlotPoint { x = 1, y = 1 }" },
7288
{ "ImDrawCornerFlags_All", "ImDrawCornerFlags.All" },
89+
{ "ImPlotFlags_None", "ImPlotFlags.None"},
90+
{ "ImPlotAxisFlags_None", "ImPlotAxisFlags.None"},
91+
{ "ImPlotAxisFlags_NoGridLines", "ImPlotAxisFlags.NoGridLines"},
92+
{ "ImGuiCond_Once", "ImGuiCond.Once"},
93+
{ "ImPlotOrientation_Vertical", "ImPlotOrientation.Vertical"},
94+
{ "PinShape_CircleFilled", "PinShape._CircleFilled"},
7395
{ "FLT_MAX", "float.MaxValue" },
74-
{ "(((ImU32)(255)<<24)|((ImU32)(255)<<16)|((ImU32)(255)<<8)|((ImU32)(255)<<0))", "0xFFFFFFFF" }
96+
{ "(((ImU32)(255)<<24)|((ImU32)(255)<<16)|((ImU32)(255)<<8)|((ImU32)(255)<<0))", "0xFFFFFFFF" },
97+
{ "sizeof(ImU8)", "sizeof(byte)"},
98+
{ "sizeof(ImS8)", "sizeof(sbyte)"},
99+
{ "sizeof(ImU16)", "sizeof(ushort)"},
100+
{ "sizeof(ImS16)", "sizeof(short)"},
101+
{ "sizeof(ImU32)", "sizeof(uint)"},
102+
{ "sizeof(ImS32)", "sizeof(int)"},
103+
{ "sizeof(ImU64)", "sizeof(ulong)"},
104+
{ "sizeof(ImS64)", "sizeof(long)"}
75105
};
76106

77107
public static readonly Dictionary<string, string> IdentifierReplacements = new Dictionary<string, string>()

0 commit comments

Comments
 (0)