-
Notifications
You must be signed in to change notification settings - Fork 278
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
ImStr / string span support #175
Comments
Did you mean string span? |
Work just begun in https://github.com/cimgui/cimgui/tree/string_view |
Work finished and examples working!! |
While working on LuaJIT wrapping I realized that ImStr to const char* susbtitution would clash with already present substitutions on imgui. So when the signature resulting from the substitution is already present in imgui the const char* version is not added now. The place where this substitution is made has changed: now the new signature is added before computation of overloading names so that naming conventions have changed. |
I find it strange to name the |
This is difficult to achieve but the postfixes can be changed:
Not sure to understand |
found a problem in IMGUI_API void Columns(int count = 1, ImStr id = NULL, bool border = true); with C versions CIMGUI_API void igColumnsStr(int count,ImStr id,bool border);
CIMGUI_API void igColumnsChpt(int count,const char* id,bool border); Not being a pointer |
Well it seems like the only reasonable answer to this problem ihmo.
Using suffixes is very polluting for anyone using completion in their IDE (everything will now appear twice).
Interesting issue, thanks. It'll work properly in C++ but be misleading.. |
So you want to change the postfixes as explained?
Yes, that would need taking care of it in LuaJIT-ImGui wrapping (not in cimgui where defaults and overloadings doesnt matter) |
No I think we should change the prefixes only.
In that case it doesn't matter which one is being called. |
The main undefinition is that not all cimgui functions have an CIMGUI_API ImGuiID ImGuiWindow_GetIDStr(ImGuiWindow* self,ImStr str);
CIMGUI_API ImGuiID ImGuiWindow_GetIDChpt(ImGuiWindow* self,const char* str);
CIMGUI_API ImGuiID ImGuiWindow_GetIDChptChpt(ImGuiWindow* self,const char* str,const char* str_end);
CIMGUI_API ImGuiID ImGuiWindow_GetIDPtr(ImGuiWindow* self,const void* ptr);
CIMGUI_API ImGuiID ImGuiWindow_GetIDInt(ImGuiWindow* self,int n); When functions are methods from a struct they take the struct prefix. One solution would be to use CIMGUI_API void igColumns(int count,ImStr id,bool border);
CIMGUI_API void SigColumns(int count,const char* id,bool border); |
As in any case I will have to adapt the code, it is not worthwhile that you make this change, I will take care of it on the LuaJIT-ImGui side. |
Just pushed to string_view with the prefix naming strategy and char* -> Str, ImStr -> STR (for backward compability) |
@ocornut gentle ping for last three messages. |
Unless I'm misunderstanding something, renaming those functions means there is NO backward compatibility? (PS: I am considering renaming ImStr to ImStrv on C++ side. This would clarify that it is a non-owning string view and not a full string holder) Let's put everything on the table. bool igIsPopupOpenSTR(ImStr str_id,ImGuiPopupFlags flags);
bool SigIsPopupOpenSTR(const char* str_id,ImGuiPopupFlags flags); const char* ImFont_CalcWordWrapPositionASTR(ImFont* self,float scale,ImStr text,float wrap_width);
const char* SImFont_CalcWordWrapPositionASTR(ImFont* self,float scale,const char* text,float wrap_width);
const char* ImFont_CalcWordWrapPositionAStr(ImFont* self,float scale,const char* text,const char* text_end,float wrap_width); int igImStrcmpStr(const char* str1,const char* str2);
int igImStrcmpSTR(ImStr str1,ImStr str2);
I tried different things and changed my mind. Right now here's what I am considering: bool ImGui_IsPopupOpen(const char* str_id,ImGuiPopupFlags flags);
bool ImGui_IsPopupOpen_Strv(ImStrv str_id,ImGuiPopupFlags flags); const char* ImFont_CalcWordWrapPositionA(ImFont* self,float scale,const char* text,float wrap_width);
const char* ImFont_CalcWordWrapPositionA_Strv(ImFont* self,float scale,ImStrv text,float wrap_width); int ImStrcmp(const char* str1,const char* str2);
int ImStrcmp_Strv(ImStr str1,ImStrv str2); Note:
About
bool igIsPopupOpen(const char* str_id,ImGuiPopupFlags flags); // classic api
bool ImGui_IsPopupOpen_Strv(ImStrv str_id,ImGuiPopupFlags flags); // string view api |
Perhaps would be useful to explain how naming is managed in cimgui: 1 - All the functions present in imgui take a prefix from a function 2 - After that when an imgui function has overloadings a postfix is added by functions In order to add A - Add this function before Actually it is done by the B path so we have for CIMGUI_API bool igIsPopupOpenID(ImGuiID id,ImGuiPopupFlags popup_flags); //from imgui_internal.h
CIMGUI_API bool igIsPopupOpenSTR(ImStr str_id,ImGuiPopupFlags flags); //from imgui.h
CIMGUI_API bool SigIsPopupOpenSTR(const char* str_id,ImGuiPopupFlags flags); //derived const char* version if name change is made to the original and not to the derived it would be CIMGUI_API bool igIsPopupOpenID(ImGuiID id,ImGuiPopupFlags popup_flags); //from imgui_internal.h
CIMGUI_API bool igIsPopupOpenSTR_Strv(ImStr str_id,ImGuiPopupFlags flags); //from imgui.h
CIMGUI_API bool igIsPopupOpenSTR(const char* str_id,ImGuiPopupFlags flags); //derived const char* version @ocornut Is this the desired one? with path A it would be CIMGUI_API bool igIsPopupOpenID(ImGuiID id,ImGuiPopupFlags popup_flags);
CIMGUI_API bool igIsPopupOpenSTR(ImStr str_id,ImGuiPopupFlags flags);
CIMGUI_API bool igIsPopupOpenStr(const char* str_id,ImGuiPopupFlags flags); And for CIMGUI_API int igImStrcmpStr(const char* str1,const char* str2);
CIMGUI_API int igImStrcmpSTR(ImStr str1,ImStr str2); There are quite things that can be changed (ImGui prefix and others) but not everything is possible with this scheme. (steps 1 and 2 and options A or B) |
Now I am answering some particular questions you made before, but the main issue should be a naming proposal according to the scheme explained above
By backward compability I meant using the same translation
Can be changed. Which translation do you prefer instead of
In imgui.h there is
What is the problem in how it is done now? They just call the ImStr version expecting implicit conversion, if they called the Strv versions there would be two levels of indirection. (C -> C -> C++)
It can be changed if you will. All the binding makers are making string substitution from ig to something. local ImGui = require"imgui.glfw"
...
ImGui.Begin("name") |
@sonoro1234 So that you know - when you make post and edit the answers afterwards we don't see the edits in e-mail notification. I generally only read message in e-mails. There's an enormous gap between initial post and after edit so good to be mindful of this :) |
Thanks for the details.
To solve the naming conflict with loose functions (not part of ImGui:: or some struct) If it was up to me I would use a int cImStrcmp(const char* str1,const char* str2);
int cImStrcmp_Strv(ImStrv str1,ImStrv str2); and then maximum consistency void cImGui_Button(...) When the prefix is added by the generator because of overloads then there's always a type suffix: bool cImGui_IsPopupOpen_ID(ImGuiID id,ImGuiPopupFlags popup_flags);
bool cImGui_IsPopupOpen_Str(const char* str_id,ImGuiPopupFlags flags);
bool cImGui_IsPopupOpen_Strv(ImStrv str_id,ImGuiPopupFlags flags); But if a function doesn't have overload it's only needed for Strv? bool cImGui_SomeFunction(const char* ...);
bool cImGui_SomeFunction_Strv(ImStrv .....);
I am talking about the C-side function/symbols name. I don't think it should be changed at will. |
It is almost imposible for me not to edit messages, specially when they are large. The only solution would be to make a new post and delete the old one. I only use github and notifications alert in order to read them.
It seems right to me. But in the case of int cImStrcmpStr(const char* str1,const char* str2);
int cImStrcmpStrv(ImStrv str1,ImStrv str2); Where I understand that for
In the case that there are not overloads for a function, no postfixes are added. ImGui::SomeFunction(ImStrv .....); The result of cimgui would be (after adding cImGui_SomeFunction(ImStrv .....);
cImGui_SomeFunction_Strv(const char*.....);
I have the impression that very few people are using cimgui just for writing C programs. For the |
Pushed changes just for |
To anyone that wants to try ImStr @repi @Jasper-Bekkers @simonvanbernem ? |
Fine to make edits/improvement to an existing post, but if you create a innocent 2 lines post and then edit it into a 2 pages post with different ideas and new questions, then people are more likely going to miss on it.
I think we are on the same page.
It may be true but we still need to serve that population. To be honest I don't have metrics of how many C users vs C# vs LUA users so we are only guessing, but I see C users on twitter.
While push the rename soon. |
Now renamed |
While trying to generate an error was found:
Shouldn't it be |
It is a function typedef instead of a function pointer typedef, it is perfectly legal but generates more ambiguities for the parser. Now working on the parser for that!! |
Will fix it to be consistent with other function pointer typedefs, sorry. |
Perhaps not necessary, I already did the changes for allowing function typedefs (not function pointer typedefs) and it seems not to break anything For ImStrv the branch with all changes is now https://github.com/cimgui/cimgui/tree/string_view2 |
I think it should be 1 task doing both things - or whatever solves the problem - you seem to insist that the current program structure cannot be reworked, so I'm not sure how to move forward. |
one task doing two things is actually two tasks |
After those two tasks are done: if there are just two overloads and one isSTRV_S drop postfix on the other. |
But this would break what I am doing in LuaJIT: when there are overloads a generic function is generated without postfixes that calls the right overload according to argument types. There would be a name clash. |
Unless the opposite is done in LuaJIT-ImGui and all other cimgui bindings... |
Two questions for short term: (1) Imagine if we released new version of dear imgui today using ImStrv: without even supporting the full Strv function could today's branch of cimgui easily provide 100% of the same functionality as today with (2) Could you provide a replacement to allow supporting
Potential replacement could be replacing Right now I don't think the function names discussed in message above are good-enough for user, so if we focus on (1) then cimgui can ship today to support an updated dear imgui (and then we can release dear imgui with ImStrv) and we can give it more time to solve those issues. We will investigate writing a "v3" of cimgui to see if we can solve those problems too. Thank you. |
Not completely sure but I think that the only difference between
|
I just want to make sure if we switch to ImStrv tomorrow people using other languages will be able to update after minor cimgui changes.
Does it means that it's only stored in the metadata field? In this case could the metadata automatically replace |
I can only be sure about LuaJIT-ImGui: All modules will run without troubles. As for other languaje bindings I guess they will be able to succeed with small changes (but really dont know)
I could be useful for LuaJIT-ImGui but then it would need to be |
@mellinoe @oprypin @lmariscal @Gekkio @Dominaezzz @ThisDrunkDane @Gnimuc @thomcc @ctreffs @vaiorabbit cimgui branch string_view2 just regenerated. |
Swift provides String initializers for C-Strings that are null-terminated code sequences. |
For Rust, creating a NUL-terminated string from a literal is inconvenient, and either requires a macro (what we have now) or allocation, so from that branch we badly want the Strv option, or something equivalent that can express non-nul-terminated strings. Beyond that, I have no strong opinions on the shape of the API, since we'll have to wrap it anyway, as calling into C is awkward and unsafe (which is disliked). I have no opinion on anything like naming conventions as I'm not going to use these from C. I'd be okay needing to pass a flags into cimgui's generator or whatever in order to generate the files with string views rather than
This would need a lot of internal changes in For users of imgui-rs, it should be fine and not break much, although we'd probably deprecate some things that would be redundant (and only exist in the Rust API). P.S. If the outcome of this ends up being that only the C++ API can use string views (and |
Thank you @thomcc for your feedback, much appreciated! |
Since Nim was designed with C interop in mind it already contains a compatible type I agree with @thomcc in that it would be nice to be able to select between |
We do have a I'm also in the camp that a build option is fine. |
Kotlin bindings require making a copy of the string to pass to C anyway, so either way is fine. |
I would not do it on a first stage. Now both versions are generated ( |
Ah, to be clear, I would only use the Strv. I only meant if there are too many problems with switching to it in cimgui by default, I don't mind passing it as a flag. I don't mind having both versions either.
Yes, same here actually, but it isn't a big deal. |
oprypin/crystal-imgui@strv Crystal has a text The naming scheme is fine, keeping both seems fine to me, but I'll switch to Something I noticed is that there are never any Also note that currently cimgui on that branch 2688f45 seems to be failing to compile on whatever compilers these were on Mac and Windows - And I am actually running into a crash:
When doing this call (i.e. when opening Widgets → Basic): https://github.com/oprypin/crystal-imgui/blob/7381050dec5949e5e7bc4eccab82f8af5b31699c/src/demo.cr#L496 The passed args are:label # => And I was going to attribute this crash purely to the C++ ImGui code Command that works fine:
|
Just pushed correction for compiling test on Debug mode and correct default values for |
For general "dear imgui side" feedback (not specific to cimgui) on the ImStrv best to post in ocornut/imgui#3038
If I am not mistaken there are only 6 functions in the public API, they all return imgui-owned-or-interned strings which are zero-terminated. If we returned ImGui
And this one specifically return 1 pointer:
Can't seem to understand how that could happen considering the difference is 2 here: (as default value is "%d")
|
I sent a link to GitHub Actions, you can see everything how I'm building there. cmake -DCMAKE_CXX_FLAGS='-DIMGUI_USE_WCHAR32' .
cmake --build . -j4 But it doesn't matter how I build;
Welp, I found it. Crystal just has a bug in passing multiple structs to a C function. I will point out, the way that arguments need to be passed (the binary interface on the stack) quickly becomes complicated, and wildly different across platforms, when structs are involved. Maybe some other language will have trouble with it too. Details about where the data got garbled by CrystalSo those values I had mentioned were printed in Crystal before passing them to the call. ImStrv.new(label) # => ImGui::ImStrv(@begin=Pointer(UInt8)@0x55940f341aac, @end=Pointer(UInt8)@0x55940f341ab4)
v # => Pointer(Int32)@0x7ffd378b0a54
v_speed # => 1.0
v_min # => 0
v_max # => 0
ImStrv.new(format) # => ImGui::ImStrv(@begin=Pointer(UInt8)@0x55940f33b7b4, @end=Pointer(UInt8)@0x55940f33b7b6)
flags # => None Then directly inside the call on the C side I already get garbled data. CIMGUI_API bool igDragInt_Strv(ImStrv label,int* v,float v_speed,int v_min,int v_max,ImStrv format,ImGuiSliderFlags flags) {
printf("%p %p, %p, %f, %d, %d, %p %p, %d\n", label.Begin, label.End, v, v_speed, v_min, v_max, format.Begin, format.End, flags); 0x55940f341aac 0x55940f341ab4, 0x7ffd378b0a54, 1.000000, 0, 0, 0x55940f33b7b6 0x78d0990700000000, 255047604 |
@oprypin @ocornut @sonoro1234 It seems to be an issue that only happens with the clang compiler. I'm having the same issues using:
The error that is shown using cmake without any aditional flags or definitions:
Using GCC 10.2.0 the same line is shown as a warning instead of an error:
I am able to compile the same files with:
And even:
|
ImHashStr issue is happening only with 64bit compilation: mingw-w64 warning and nmake error. The only solution I can think is wrapping argument in CIMGUI_API ImGuiID igImHashStr_StrU32(const char* str,ImU32 seed)
{
return ImHashStr(ImStrv(str),seed);
} I will wrap into |
Just pushed change. Is that ok? |
@oprypin |
@sonoro1234 Please don't let that bug affect decisions here :) And thanks for the change to resolve that compiler warning/error. It works. |
This issue is too long so I open another issue to continue: #186 |
Followup to ocornut/imgui#3038 (comment)
We are planing (maybe around 1.82) to add support for spring span everywhere in Dear ImGui.
This mean that strings won't need to be zero-terminated.
This will have multiple benefits:
ImGui::Text("Hello")
will compile asImStr("Hello", 5)
as the compiler can optimize the strlen() down to 5. This has been proven to give some benefits. For non-literal, the call to strlen() is done once at call site.Instead they could do:
However this will need support from cimgui.
I believe the best solution is that cimgui provide TWO api, with both always available.
const char*
and inline call the first API:igText(const char* str) { igsText(str, str + strlen(str); }
User who actually write code in C will want to use API (2).
Old bindings can use API (2). But we want improving bindings to use API (1).
So from any languages, such as Lua or also .Net/C#, we want user to never see anything about ImStr() (or double
const char*
) and use their normal string, and the language back-end should automatically do this conversion and use the native string type length to avoid strlen call as a bonus.How would that work with Lua-JIT and e.g. C# ? (cc @mellinoe)
The text was updated successfully, but these errors were encountered: