Skip to content

Commit 5e6568e

Browse files
committed
Refactor build system for ImGui targets and configurations
Updated `Generator.csproj` to remove `Newtonsoft.Json` and add `HexaGen.BuildSystems`. Refactored `Program.cs` to simplify target management using `BuildSystemBuilder`. Introduced new files for handling ImGui add-ons, backends, and core library generation, enhancing modularity and maintainability.
1 parent e63d45d commit 5e6568e

File tree

7 files changed

+408
-233
lines changed

7 files changed

+408
-233
lines changed

Generator/Generator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<ItemGroup>
1313
<PackageReference Include="HexaGen" Version="1.1.10" />
14-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
14+
<PackageReference Include="HexaGen.BuildSystems" Version="0.0.1-alpha" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

Generator/Program.cs

Lines changed: 14 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -1,241 +1,23 @@
1-
#define BackendsOnly
2-
//#define DisableBackends
3-
//#define NodeEditorOnly
4-
5-
namespace Generator
1+
namespace Generator
62
{
7-
using HexaGen;
8-
using HexaGen.Core.Logging;
9-
using HexaGen.Core.Mapping;
10-
using Microsoft.CodeAnalysis;
11-
using System.Text.Json;
12-
using HexaGen.Metadata;
13-
using HexaGen.Patching;
3+
using Generator.Targets;
4+
using HexaGen.BuildSystems;
145

156
internal unsafe class Program
167
{
17-
private const string CImGuiConfig = "cimgui/generator.json";
18-
19-
private const string CImGuizmoConfig = "cimguizmo/generator.json";
20-
private const string CImNodesConfig = "cimnodes/generator.json";
21-
private const string CImPlotConfig = "cimplot/generator.json";
22-
23-
private const string ImGuiNodeEditorConfig = "imgui-node-editor/generator.json";
24-
25-
private const string CImGuiHeader = "cimgui/cimgui.h";
26-
private const string CImGuizmoHeader = "cimguizmo/cimguizmo.h";
27-
private const string CImNodesHeader = "cimnodes/cimnodes.h";
28-
private const string CImPlotHeader = "cimplot/cimplot.h";
29-
30-
private const string ImGuiNodeEditorHeader = "imgui-node-editor/imgui_node_editor.h";
31-
32-
private const string ImGuiOutputPath = "../../../../Hexa.NET.ImGui/Generated";
33-
34-
private const string ImGuizmoOutputPath = "../../../../Hexa.NET.ImGuizmo/Generated";
35-
private const string ImNodesOutputPath = "../../../../Hexa.NET.ImNodes/Generated";
36-
private const string ImPlotOutputPath = "../../../../Hexa.NET.ImPlot/Generated";
37-
38-
private const string ImGuiNodeEditorOutputPath = "../../../../Hexa.NET.ImGuiNodeEditor/Generated";
39-
private const string ImGuiBackendsOutputPath = "../../../../Hexa.NET.ImGui.Backends/Generated";
40-
private const string ImGuiBackendsSDL2OutputPath = "../../../../Hexa.NET.ImGui.Backends.SDL2/Generated";
41-
private const string ImGuiBackendsSDL3OutputPath = "../../../../Hexa.NET.ImGui.Backends.SDL3/Generated";
42-
private const string ImGuiBackendsGLFWOutputPath = "../../../../Hexa.NET.ImGui.Backends.GLFW/Generated";
43-
private const string CImGuiBackendsHeader = "backends/cimgui_impl.h";
44-
private const string CImGuiBackendsConfig = "backends/generator.json";
45-
private const string CImGuiBackendsSDL2Config = "backends/generator.sdl2.json";
46-
private const string CImGuiBackendsSDL3Config = "backends/generator.sdl3.json";
47-
private const string CImGuiBackendsGLFWConfig = "backends/generator.glfw.json";
48-
498
private static void Main(string[] args)
509
{
51-
if (Directory.Exists("patches"))
52-
{
53-
Directory.Delete("patches", true);
54-
}
55-
56-
Directory.CreateDirectory("./patches");
57-
58-
#if !NodeEditorOnly
59-
60-
#if !BackendsOnly
61-
// don't worry about "NoInternals" internals will be generated in a substep (post-patch) when generating. see ImGuiPostPatch.cs
62-
Generate([CImGuiHeader], CImGuiConfig, ImGuiOutputPath, null, out var metadata, InternalsGenerationType.NoInternals);
63-
64-
Generate([CImGuizmoHeader], CImGuizmoConfig, ImGuizmoOutputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
65-
Generate([CImPlotHeader], CImPlotConfig, ImPlotOutputPath, metadata, out var imPlotMetadata, InternalsGenerationType.BothOrDontCare);
66-
Generate([CImNodesHeader], CImNodesConfig, ImNodesOutputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
67-
#else
68-
Generate([CImGuiHeader], CImGuiConfig, ImGuiOutputPath, null, out var metadata, InternalsGenerationType.NoInternals);
69-
#endif
70-
71-
#if !DisableBackends
72-
string[] backends = ["OpenGL3", "OpenGL2", "D3D9", "D3D10", "D3D11", "D3D12", "Vulkan", "Win32", "OSX", "Metal", "Android"];
73-
74-
metadata.CppDefinedFunctions.Clear();
75-
76-
CsCodeGeneratorMetadata? metadataBackend = new()
77-
{
78-
FunctionTable = new() { Entries = [new(0, "igSetCurrentContext"), new(1, "igGetCurrentContext")] },
79-
Settings = new(),
80-
WrappedPointers = metadata.WrappedPointers.ToDictionary()
81-
};
82-
83-
foreach (string lib in backends)
84-
{
85-
GenerateBackend(["backends/cimgui.h", CImGuiBackendsHeader], CImGuiBackendsConfig, ImGuiBackendsOutputPath, metadataBackend, out var libMetadata, lib);
86-
metadataBackend ??= libMetadata;
87-
}
88-
89-
Generate(["backends/cimgui.h", CImGuiBackendsHeader], CImGuiBackendsSDL2Config, ImGuiBackendsSDL2OutputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
90-
Generate(["backends/cimgui.h", CImGuiBackendsHeader], CImGuiBackendsSDL3Config, ImGuiBackendsSDL3OutputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
91-
Generate(["backends/cimgui.h", CImGuiBackendsHeader], CImGuiBackendsGLFWConfig, ImGuiBackendsGLFWOutputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
92-
#endif
93-
94-
#else
95-
96-
GenerateNodeEditor(ImGuiNodeEditorHeader, ImGuiNodeEditorConfig, ImGuiNodeEditorOutputPath, null, out _);
97-
98-
#endif
99-
100-
Console.ForegroundColor = ConsoleColor.DarkGreen;
101-
Console.WriteLine("All Done!");
102-
Console.ForegroundColor = ConsoleColor.White;
103-
}
104-
105-
private static bool GenerateNodeEditor(string header, string settingsPath, string output, CsCodeGeneratorMetadata? lib, out CsCodeGeneratorMetadata metadata)
106-
{
107-
CsCodeGeneratorConfig settings = CsCodeGeneratorConfig.Load(settingsPath);
108-
settings.SystemIncludeFolders.Add("C:/dev/imgui");
109-
settings.WrapPointersAsHandle = true;
110-
ImGuiCodeGenerator generator = new(settings);
111-
generator.PatchEngine.RegisterPrePatch(new ImVectorPatch());
112-
generator.PatchEngine.RegisterPostPatch(new ImGuiNodeEditorPostPatch());
113-
114-
generator.LogToConsole();
115-
116-
if (lib != null)
117-
{
118-
generator.CopyFrom(lib);
119-
}
120-
121-
bool result = generator.Generate(header, output);
122-
metadata = generator.GetMetadata();
123-
124-
return result;
125-
}
126-
127-
private static bool Generate(string[] headers, string settingsPath, string output, CsCodeGeneratorMetadata? lib, out CsCodeGeneratorMetadata metadata, InternalsGenerationType type)
128-
{
129-
CsCodeGeneratorConfig settings = CsCodeGeneratorConfig.Load(settingsPath);
130-
settings.Defines.Add("IMGUI_USE_WCHAR32");
131-
settings.Defines.Add("IMGUI_ENABLE_FREETYPE");
132-
settings.WrapPointersAsHandle = true;
133-
134-
ImGuiCodeGenerator generator = new(settings);
135-
generator.PatchEngine.RegisterPrePatch(new ImVectorPatch());
136-
generator.PatchEngine.RegisterPrePatch(new ImGuiDefinitionsPatch(type));
137-
generator.PatchEngine.RegisterPrePatch(new ImGuizmoPrePatch());
138-
generator.PatchEngine.RegisterPrePatch(new ImGuiPrePatch());
139-
generator.PatchEngine.RegisterPrePatch(new NamingPatch(["CImGui", "ImGui", "ImGuizmo", "ImNodes", "ImPlot", "ImplSDL2", "ImplSDL3", "ImplGlfw", "Impl"], NamingPatchOptions.MultiplePrefixes));
140-
generator.PatchEngine.RegisterPostPatch(new ImGuiPostPatch());
141-
generator.PatchEngine.RegisterPostPatch(new ImGuiBackendsPostPatch());
142-
generator.PatchEngine.RegisterPostPatch(new ImGuiImGuiDataTypePrivatePatch());
143-
144-
generator.LogToConsole();
145-
146-
if (lib != null)
147-
{
148-
generator.CopyFrom(lib);
149-
}
150-
151-
bool result = generator.Generate([.. headers], output);
152-
metadata = generator.GetMetadata();
153-
154-
File.WriteAllText(settings.LibName + ".log", string.Join(Environment.NewLine, generator.Messages.Select(x => x.ToString())));
155-
156-
return result;
157-
}
158-
159-
private static bool GenerateBackend(string[] headers, string settingsPath, string output, CsCodeGeneratorMetadata? lib, out CsCodeGeneratorMetadata metadata, string name)
160-
{
161-
CsCodeGeneratorConfig settings = CsCodeGeneratorConfig.Load(settingsPath);
162-
settings.Defines.Add("IMGUI_USE_WCHAR32");
163-
settings.Defines.Add("IMGUI_ENABLE_FREETYPE");
164-
settings.WrapPointersAsHandle = true;
165-
166-
string[] strings =
167-
[
168-
$"CIMGUI_USE_GLFW={(name == "GLFW" ? "1":"0")}",
169-
$"CIMGUI_USE_SDL2={(name == "SDL2" ? "1":"0")}",
170-
$"CIMGUI_USE_SDL2Renderer={(name == "SDL2" ? "1":"0")}",
171-
$"CIMGUI_USE_SDL3={(name == "SDL3" ? "1":"0")}",
172-
$"CIMGUI_USE_SDL3Renderer={(name == "SDL3" ? "1":"0")}",
173-
$"CIMGUI_USE_OPENGL3={(name == "OpenGL3" ? "1":"0")}",
174-
$"CIMGUI_USE_OPENGL2={(name == "OpenGL2" ? "1":"0")}",
175-
$"CIMGUI_USE_D3D9={(name == "D3D9" ? "1":"0")}",
176-
$"CIMGUI_USE_D3D10={(name == "D3D10" ? "1":"0")}",
177-
$"CIMGUI_USE_D3D11={(name == "D3D11" ? "1":"0")}",
178-
$"CIMGUI_USE_D3D12={(name == "D3D12" ? "1":"0")}",
179-
$"CIMGUI_USE_VULKAN={(name == "Vulkan" ? "1":"0")}",
180-
$"CIMGUI_USE_WIN32={(name == "Win32" ? "1":"0")}",
181-
$"CIMGUI_USE_METAL={(name == "Metal" ? "1":"0")}",
182-
$"CIMGUI_USE_OSX={(name == "OSX" ? "1":"0")}",
183-
$"CIMGUI_USE_ANDROID={(name == "Android" ? "1":"0")}"];
184-
185-
var originalNamespace = settings.Namespace;
186-
187-
settings.Defines.AddRange(strings);
188-
settings.ApiName = $"ImGuiImpl{name}";
189-
settings.Namespace += $".{name}";
190-
191-
string ignoreName = name switch
192-
{
193-
"SDL2" => "ImplSDL2",
194-
"SDL3" => "ImplSDL3",
195-
"GLFW" => "ImplGlfw",
196-
"D3D9" => "ImplDX9",
197-
"D3D10" => "ImplDX10",
198-
"D3D11" => "ImplDX11",
199-
"D3D12" => "ImplDX12",
200-
_ => $"Impl{name}"
201-
};
202-
203-
ImGuiCodeGenerator generator = new(settings);
204-
generator.PatchEngine.RegisterPrePatch(new ImVectorPatch());
205-
generator.PatchEngine.RegisterPrePatch(new NamingPatch(["CImGui", "ImGui", "ImGuizmo", "ImNodes", "ImPlot", ignoreName], NamingPatchOptions.MultiplePrefixes));
206-
generator.PatchEngine.RegisterPostPatch(new ImGuiBackendsPostPatch());
207-
208-
generator.LogToConsole();
209-
210-
if (lib != null)
211-
{
212-
settings.FunctionTableEntries.AddRange(lib.FunctionTable.Entries);
213-
generator.CopyFrom(lib);
214-
}
215-
216-
if (name == "Win32")
217-
{
218-
name = "Windows";
219-
}
220-
221-
var originalOutput = output;
222-
output = Path.Combine(output, name);
223-
224-
bool result = generator.Generate([.. headers], output);
225-
metadata = generator.GetMetadata();
226-
227-
File.WriteAllText(settings.LibName + ".log", string.Join(Environment.NewLine, generator.Messages.Select(x => x.ToString())));
228-
229-
lib?.Merge(metadata, true);
230-
231-
string destPath = Path.Combine(originalOutput, "FunctionTable.cs");
232-
File.Move(Path.Combine(output, "FunctionTable.cs"), destPath, true);
233-
234-
string text = File.ReadAllText(destPath);
235-
text = text.Replace(settings.ApiName, "ImGuiImpl").Replace(settings.Namespace, originalNamespace);
236-
File.WriteAllText(destPath, text);
237-
238-
return result;
10+
var builder = BuildSystemBuilder.Create()
11+
.WithArgs(args)
12+
.AddImGui()
13+
.AddImPlot()
14+
.AddImNodes()
15+
.AddImGuizmo()
16+
.AddImGuiBackends()
17+
.AddImGuiNodeEditor(false);
18+
19+
var context = builder.Build();
20+
context.Execute();
23921
}
24022
}
24123
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
namespace Generator.Targets
2+
{
3+
using HexaGen.BuildSystems;
4+
using System.Collections.Generic;
5+
6+
public class ImGuiAddonTargetOptions
7+
{
8+
public string Name { get; set; } = null!;
9+
10+
public List<string> Headers { get; set; } = [];
11+
12+
public string ConfigPath { get; set; } = null!;
13+
14+
public string OutputPath { get; set; } = null!;
15+
}
16+
17+
public static class ImGuiAddonTargetExtensions
18+
{
19+
private const string CImGuizmoConfig = "cimguizmo/generator.json";
20+
private const string CImNodesConfig = "cimnodes/generator.json";
21+
private const string CImPlotConfig = "cimplot/generator.json";
22+
23+
private const string CImGuizmoHeader = "cimguizmo/cimguizmo.h";
24+
private const string CImNodesHeader = "cimnodes/cimnodes.h";
25+
private const string CImPlotHeader = "cimplot/cimplot.h";
26+
27+
private const string ImGuizmoOutputPath = "../../../../Hexa.NET.ImGuizmo/Generated";
28+
private const string ImNodesOutputPath = "../../../../Hexa.NET.ImNodes/Generated";
29+
private const string ImPlotOutputPath = "../../../../Hexa.NET.ImPlot/Generated";
30+
31+
public static BuildSystemBuilder AddImGuizmo(this BuildSystemBuilder builder, string configPath = CImGuizmoConfig, string outputPath = ImGuizmoOutputPath)
32+
{
33+
builder.AddTarget<ImGuiAddonTarget, ImGuiAddonTargetOptions>("imguizmo", options =>
34+
{
35+
options.Name = "imguizmo";
36+
options.Headers = [CImGuizmoHeader];
37+
options.ConfigPath = configPath;
38+
options.OutputPath = outputPath;
39+
});
40+
return builder;
41+
}
42+
43+
public static BuildSystemBuilder AddImNodes(this BuildSystemBuilder builder, string configPath = CImNodesConfig, string outputPath = ImNodesOutputPath)
44+
{
45+
builder.AddTarget<ImGuiAddonTarget, ImGuiAddonTargetOptions>("imnodes", options =>
46+
{
47+
options.Name = "imnodes";
48+
options.Headers = [CImNodesHeader];
49+
options.ConfigPath = configPath;
50+
options.OutputPath = outputPath;
51+
});
52+
return builder;
53+
}
54+
55+
public static BuildSystemBuilder AddImPlot(this BuildSystemBuilder builder, string configPath = CImPlotConfig, string outputPath = ImPlotOutputPath)
56+
{
57+
builder.AddTarget<ImGuiAddonTarget, ImGuiAddonTargetOptions>("implot", options =>
58+
{
59+
options.Name = "implot";
60+
options.Headers = [CImPlotHeader];
61+
options.ConfigPath = configPath;
62+
options.OutputPath = outputPath;
63+
});
64+
return builder;
65+
}
66+
}
67+
68+
public class ImGuiAddonTarget : ImGuiBaseTarget
69+
{
70+
private readonly List<string> headers;
71+
private readonly string configPath;
72+
private readonly string outputPath;
73+
74+
public ImGuiAddonTarget(ImGuiAddonTargetOptions options)
75+
{
76+
Name = options.Name;
77+
headers = options.Headers;
78+
configPath = options.ConfigPath;
79+
outputPath = options.OutputPath;
80+
}
81+
82+
public ImGuiAddonTarget(string name, IEnumerable<string> headers, string configPath, string outputPath)
83+
{
84+
Name = name;
85+
this.headers = [.. headers];
86+
this.configPath = configPath;
87+
this.outputPath = outputPath;
88+
}
89+
90+
public override string Name { get; }
91+
92+
public override IReadOnlyList<string> Dependencies { get; } = ["imgui"];
93+
94+
public override void Execute(BuildContext context)
95+
{
96+
var metadata = GetImGuiMetadata(context);
97+
Generate(headers, configPath, outputPath, metadata, out _, InternalsGenerationType.BothOrDontCare);
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)