-
Notifications
You must be signed in to change notification settings - Fork 6
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
How to support nanobind? #3
Comments
Hello, If you want to do this, here are some advices:
litgen is not a small library, so I think you may encounter a few subtleties, such as how to make methods overridable, which is very much linked to pybind11 at the moment. If you take this route, please keep me informed of your progress! thanks |
Hello, could you give me more information about your current status? Did you manage to get something working? If so, I would be interested in having more information. Thanks. |
Hey @pthom, sorry for being late! We did manage to get our nanobind flavor imgui binding, here's what I did: About this one particular commit davidlatwe@19b4826 in my
Somehow, ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end = NULL, ...) It has to be like this: m.def("CalcTextSize", [](const char * text, std::optional<std::string> text_end = std::nullopt, ...)
{
auto CalcTextSize_adapt = [](const char * text, std::optional<std::string> text_end = std::nullopt, ...)
{
const char * text_end_adapt_default_null = nullptr;
if (text_end.has_value())
text_end_adapt_default_null = text_end.value().c_str();
auto lambda_result = ImGui::CalcTextSize(text, text_end_adapt_default_null, ...);
return lambda_result;
};
return CalcTextSize_adapt(text, text_end, ...);
},
py::arg("text"), py::arg("text_end") = py::none(), ...); I am sure there are still some bugs in our imgui nanobind binding, but it is working great so far for our goals. But util now though, because I found that I have to also try supporting older versions of Python which are not supported by nanobind, so I am going back to pybind11 at the moment. (Our library runs in another application which has its own Python embedded from 2.7-3.11+ depends on its version. And we have Python 3.11+ embedded in our library and ImGui will be bound with it for internal GUI drawing. We'd like to use only one binding library through out entire project. So although ImGui is aimed to Python 3.11+, our other bindings are aimed to the host application for public use. Therefore we now have to go with pybind11 v2.9.2 to see if that works.) Oh and, about this one:
I have not done that yet 😅 I installed my litgen fork in a import os
import shutil
# ./external/imgui_bundle/external/imgui/bindings/generate_imgui.py
import generate_imgui
ROOT = os.path.dirname(__file__)
@generate_imgui.my_time_it
def generate():
# Note: Don't need imgui_test_engine, so not using `generate_imgui.main()`
# Note: Don't need, but also cannot bind imgui_internal because `GImGui`
# symbol is unresolvable by linker.
generate_imgui.autogenerate_imgui()
stub_dir = generate_imgui.STUB_DIR
pydef_dir = generate_imgui.PYDEF_DIR
wrapper_dir = os.path.join(os.path.dirname(pydef_dir), "imgui_pywrappers")
files = [
# cpp
os.path.join(pydef_dir, "nanobind_imgui.cpp"),
# pyi
os.path.join(stub_dir, "imgui/__init__.pyi"),
# wrapper
os.path.join(wrapper_dir, "imgui_pywrappers.cpp"),
os.path.join(wrapper_dir, "imgui_pywrappers.h"),
]
return files
def to_nanobind(file):
with open(file, "r") as fp:
lines = fp.readlines()
in_text_buffer_class = False
in_text_buffer_delete = False
new_lines = []
for line in lines:
# error LNK2001: unresolved external symbol "public:
# static char * ImGuiTextBuffer::EmptyString"
if "auto pyClassImGuiTextBuffer =" in line:
in_text_buffer_class = True
if in_text_buffer_class:
if '.def("begin",' in line or '.def("c_str",' in line:
in_text_buffer_delete = True
if '.def("size",' in line:
in_text_buffer_delete = False
if '.def("append",' in line:
in_text_buffer_delete = False
in_text_buffer_class = False
if in_text_buffer_delete:
continue
line = line.replace(" = NULL", " = nullptr")
new_lines.append(line)
with open(file, "w") as fp:
fp.writelines(new_lines)
def run():
# Generate binding
files = generate()
# Copy generated file
out_dir = os.path.join(ROOT, "src")
cpp_files = []
for src in files:
fname = os.path.basename(src)
if fname.endswith(".cpp") or fname.endswith(".h"):
cpp_files.append(fname)
shutil.copy2(src, os.path.join(out_dir, fname))
# Final nanobind related cleanup
for fname in cpp_files:
to_nanobind(os.path.join(out_dir, fname))
if __name__ == "__main__":
run() |
Hello, Thanks for the details info! You went far into the customization, since I see you added a specific adapter (which is deep inside litgen internals). Note: your
There is no rush. Adding this to litgen would require additional effort (integration tests, polishing, etc.); all of which is time consuming, I know. If you have time to work on it later, I would appreciate it; but it depends on whether you have time to invest on it or not.
May I ask what kind of project you are working on? |
😊
Thanks! Yeah, it was easy enough to get my way. With some simple text search, I can learn where I need to go. And the variable/function naming is quite clear. This is us 👋🏼 : https://ragdolldynamics.com/ We use ImGui to draw our user interface on the 3D viewport in another application like Maya/Blender. You can find the trace of ImGui in here: https://learn.ragdolldynamics.com/tutorials/manikin/#shapes At the moment, our user interface was written in C++, but in the futrue we may enable our clients the ability to make their own UI with our embedded Python and ImGui Python binding. To do so, there can have only one By the way, here is one interesting thing I found. When I build the binding with nanobind from our original ImGui source code, the build works without any problem. But when I switch back to pybind11, I got error like |
It has been a few months since there has been activity on this issue. Is there a path forward for litgen to support automatic nanobind code generation? If that's a feature that can be supported, I'd love to use this tool in one of my projects. Thanks! |
Hey @mattparks , nanobind support currently only available from my forks: And I only did the necessary changes for my own project so not fully tested. If possible, you can give my forks a shot. In the mean time, I will try submit a PR. |
Hi @davidlatwe I had a deep look at your branches for litgen, and imgui_bundle, and it is indeed a very thorough and nice work. Congrats! I hope someday it will be possible to merge it. Feel free to open a PR, even if not complete. It might remain as a separate branch in a first step. |
Thanks for asking! Pull requests created 😃 |
Hi @pthom ,
If I want to integrate
litgen
withnanobind
, make it able to chose the flavor of binding, what would you suggest?There are lots of small differences between the two, like:
.def_property
->.def_prop_rw
obj.cast<bool>()
->py::cast<bool>(obj)
Although they can be done with
str.replace()
,regex
and some hardwork, but iflitgen
can add one new flavor that would be awesome.Thanks. :)
The text was updated successfully, but these errors were encountered: