-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option for handling internals #364
base: master
Are you sure you want to change the base?
Conversation
{ | ||
string outputPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure why github has decided to diff this in this way, but this is all new code apart from the declarations of the outputPath
and libraryName
variables which was moved up from below. You can see this code in raw format in this comment. This does a few things:
- Creates three parameters
- Adds them to the command line parser
- Runs the parser
- If the parser passes, it moves on to the normal logic you had in this file which now starts on line 89
src/CodeGenerator/Program.cs
Outdated
foreach (FunctionDefinition fd in defs.Functions) | ||
EmitFunctions(false); | ||
writer.PopBlock(); | ||
writer.PopBlock(); | ||
|
||
if (useInternals) | ||
{ | ||
if (TypeInfo.SkippedFunctions.Contains(fd.Name)) { continue; } | ||
writer.PushBlock($"namespace {projectNamespace}{InternalNamespace}"); | ||
writer.PushBlock($"public static unsafe partial class {classPrefix}"); | ||
EmitFunctions(true); | ||
writer.PopBlock(); | ||
writer.PopBlock(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This runs the function overload processing logic twice, once for non-internals, to put things in the ImGuiNET.ImGui
class, and then a second time for internals which go into the ImGuiNET.Internal.ImGui
class.
|
||
foreach (OverloadDefinition overload in fd.Overloads) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code was promoted to a local function so it could run twice, with the internal flag set or not. The code is the same except for line 433. Originally this method does a ton of processing on the member data only to do a final check, if it isn't a member function (and thus belongs on the ImGui
class) then returns. I'm unsure why that was done at the end of all the logic, so I moved it here to just filter them out at the start. Now this loop ONLY processes non-member functions.
|
||
for (int i = overload.DefaultValues.Count; i >= 0; i--) | ||
{ | ||
if (overload.IsMemberFunction) { continue; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the line I removed and added to the main loop to filter out member functions.
src/CodeGenerator/TypeInfo.cs
Outdated
// internals | ||
{ "char[5]", "byte*"}, | ||
{ "ImGuiDir*", "IntPtr" }, | ||
//{ "ImGuiStoragePair", "IntPtr" }, | ||
{ "ImGuiDockRequest", "IntPtr" }, | ||
{ "ImGuiDockNodeSettings", "IntPtr" }, | ||
{ "ImGuiTableColumnIdx", "sbyte" }, | ||
{ "ImGuiTableDrawChannelIdx", "byte"}, | ||
{ "ImGuiContextHookCallback", "IntPtr" }, | ||
{ "ImGuiErrorLogCallback", "IntPtr" }, | ||
//{ "ImGuiSizeCallback", "IntPtr"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was taken from #273 and I'm not totally sure how it all works or if it's correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only remember vaguely, but I think I found those by manual "trial and error". Added them here as they were causing erors in the generated internals C# code.
I found these values by looking at the existing TypeInfos, was pretty straight forward to define the mappings:
- Structs and pointers were mapped to IntPtr
- IDs were mapped to byte/sbyte (might work if both are sbyte, don't remember if the unsigned byte was intentional)
- Char array was mapped to byte pointer, as chars are represented as bytes and arrays need to be pointers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what should be added to these sections as the PR is 2 years old and I don't know what new types need to be defined.
Hi @Thraka, glad that you could use something from the PR, that's what I uploaded it for after all! Didn't have much time to follow up unfortunately, switched jobs and all that jazz |
One thing that I don't understand is when generating internals, it creates Even so, I generated the internals and copied over a bunch of the source files to my project just so I could access |
I've also been looking into getting access to ImGui's internals, which are often being advertised as solutions or at least workarounds to questions people have in ImGui's issue tracker. In my case, docking, clearing an element's focus, and modifying the selection of a text input are all not possible with the current C# bindings, since the necessary functions are not exposed. After much messing around, I was able to get a modified version of Thraka's branch working. Official support would be of course very much appreciated. However I wouldn't have made a post to just say this. In this PR, it appears that internal functions are placed in |
I put everything into a separate namespace to mimic what ImGui does, the internals are only ever pulled in when you reference the internals header. I thought this would be a decent enough separation where you can easily see what is internal and what is non-internal. I do like the What I've been doing is just importing the class directly as using ImGuiInternal = ImGuiNET.Internal.ImGui; |
@zaafar is there a chance that this can be shipped? Idk what your role is in this project, but you seem to be merging things when eric is not around? :) |
@deccer i forgot about this PR, give me few days I will get it merged. |
@zaafar if you're actually going to spend time on this PR, I'll schedule some time to pull down the latest locally and make sure everything still works. I've just been using the version I compiled this for, so I've not had a need to revisit it. Let me know. I fixed the merge conflict at least. |
This update is proving to be a lot more difficult and past my ability.... I don't know what to do with these very complex internal types that there's no code generation definitions for. Some of these types evolved from the previous 1.88 version which the code generator could handle with internals. Some examples: struct ImDrawDataBuilder
{
ImVector<ImDrawList*>* Layers[2]; // Pointers to global layers for: regular, tooltip. LayersP[0] is owned by DrawData.
ImVector<ImDrawList*> LayerData1;
ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); }
}; In the generated public RangeAccessor<ImVector*> Layers => new RangeAccessor<ImVector*>(&NativePtr->Layers_0, 2); Also, the ImGui CPP code is using unions in some structures such as struct ImGuiStyleMod
{
ImGuiStyleVar VarIdx;
union { int BackupInt[2]; float BackupFloat[2]; };
ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
}; And the current code generation system doesn't know what to do with that. There are also these helpers from the ImGui code that don't get translated. I'm not sure what to do with these. For example, take The Generated code: public unsafe partial struct ImGuiTable
{
...
public ImSpan_ImGuiTableColumn Columns;
public ImSpan_ImGuiTableColumnIdx DisplayOrderToIndex;
public ImSpan_ImGuiTableCellData RowCellData;
public ImBitArrayPtr EnabledMaskByDisplayOrder;
public ImBitArrayPtr EnabledMaskByIndex;
public ImBitArrayPtr VisibleMaskByIndex;
... |
@zaafar Please read my previous post, I've updated it if you already read it. As this PR stands now, it has code changes to restructure the command line system of the code generator, and handles internals when Handling the actual code generation for internals, however, doesn't work anymore. It worked with The quicker this gets accepted, the better 😁 just so I don't have to keep coming back and tweaking. Right now I'm stuck on Cheers! --- Edit, additional --- |
any news? |
sorry about that, I got busy in job. i want to merge this one but it can only happen once I (or someone with push access) can review it. |
Hi @mellinoe I know you're crazy busy with life and other projects, but I wanted to throw this out there.
(Separate ping to @JulianVallee thank you for your other PR. I used it as inspiration for this PR (and I took a few things here or there), but I reduced the scope to improve the likelihood that it's merged or at least looked at, since it's a bit simpler.)
This PR is similar to #273 except it contains just what is necessary to get something working. It's not trying to actually update the release build in any way. I've tested omitting the
--internal
command line parameter and it outputs exactly the same content (according to git) as your current master branch.This PR does the following:
The way this works is
Sets up three parameters that can be set on the command line. Here is the
--help
info:The variables used by Program.cs remain but are initialized by the command line parser for default values:
outputPath
andlibraryName
.A new variable is introduced,
useInternals
, which is set to true when the--internal
parameter is set.ImGuiDefinitions.LoadFrom
now has a parameter to indicate that internal members should be loaded.When Enums, Types, and Functions are loaded, they're checked for the internal flag in the definition file and set on the corresponding class definition types.
When processing all of the loaded definitions, types and enums that are internal are added to the
ImGuiNET.Internal
namespace.When processing the main
ImGui
type, it's done twice, first excluding any internal member, then a second time if the internal flag was set, adding these to theImGuiNET.Internal.ImGui
class.Processing the file in this way keeps the public facing API
ImGuiNET.ImGui
clean and free of any internal members. I think this is a good compromise so people can understand what they're doing and what they're accessing.When the code generator runs with the internal mode on, it doesn't generate a compilable project. There are all sorts of little things to handle, some done by the other PR I linked to #273. I'm not sure how you want to further enhance the code generator to handle this. I also don't know a ton about C++ and I'm unsure what to do to handle a lot of things. I don't know how you would want to handle the two types that have
union
members for example.