Skip to content

Commit

Permalink
ImmApp: add ManualRender utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Nov 21, 2024
1 parent 6ea79ae commit b7a73b2
Show file tree
Hide file tree
Showing 8 changed files with 430 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "immapp/immapp.h"
#include "imgui_md_wrapper/imgui_md_wrapper.h"
#include "hello_imgui/hello_imgui.h"
#include "imgui.h"


void Gui()
{
ImGuiMd::RenderUnindented(R"(
# Sandbox
Lorem ipsum dolor sit amet, consectetur adipiscing elit
)");
if (ImGui::Button("Save"))
{
// Save something
}
ImGui::SameLine();
if (ImGui::Button("Load"))
{
// Load something
}
}

int main(int, char **)
{

//ImmApp::Run(runnerParams, addonsParams);

{
HelloImGui::RunnerParams runnerParams;
runnerParams.callbacks.ShowGui = Gui;
ImmApp::AddOnsParams addonsParams;
addonsParams.withMarkdown = true;

ImmApp::ManualRender::SetupFromRunnerParams(runnerParams, addonsParams);
while(!HelloImGui::GetRunnerParams()->appShallExit)
ImmApp::ManualRender::Render();
ImmApp::ManualRender::TearDown();
}

{
ImmApp::ManualRender::SetupFromGuiFunction(
Gui,
"Sandbox", // windowTitle
false, // windowSizeAuto
false, // windowRestorePreviousGeometry
ImmApp::DefaultWindowSize, // windowSize
10.f, // fpsIdle
false, // withImplot
true, // withMarkdown
false // withNodeEditor
);
while(!HelloImGui::GetRunnerParams()->appShallExit)
ImmApp::ManualRender::Render();
ImmApp::ManualRender::TearDown();
}

{
HelloImGui::SimpleRunnerParams runnerParams;
runnerParams.guiFunction = Gui;
ImmApp::AddOnsParams addonsParams;
addonsParams.withMarkdown = true;
ImmApp::ManualRender::SetupFromSimpleRunnerParams(runnerParams, addonsParams);
while(!HelloImGui::GetRunnerParams()->appShallExit)
ImmApp::ManualRender::Render();
ImmApp::ManualRender::TearDown();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from imgui_bundle import immapp, hello_imgui, imgui_md, imgui


def gui():
imgui_md.render_unindented("""
# Sandbox
Lorem ipsum dolor sit amet, consectetur adipiscing elit
""")
if imgui.button("Save"):
# Save something
pass
imgui.same_line()
if imgui.button("Load"):
# Load something
pass


def main():
immapp.manual_render.setup_from_gui_function(gui)
while not hello_imgui.get_runner_params().app_shall_exit:
immapp.manual_render.render()
immapp.manual_render.tear_down()


if __name__ == "__main__":
main()
main()
main()
7 changes: 6 additions & 1 deletion bindings/imgui_bundle/immapp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Part of ImGui Bundle - MIT License - Copyright (c) 2022-2023 Pascal Thomet - https://github.com/pthom/imgui_bundle
from imgui_bundle import _imgui_bundle as _native_bundle
from imgui_bundle._imgui_bundle import immapp_cpp as immapp_cpp # type: ignore
from imgui_bundle._imgui_bundle.immapp_cpp import ( # type: ignore
clock_seconds,
Expand Down Expand Up @@ -32,7 +33,7 @@
# runner_params.callbacks.default_icon_font = hello_imgui.DefaultIconFont.font_awesome6
from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome_4
from imgui_bundle.immapp import icons_fontawesome_6 as icons_fontawesome_6
from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome # v4
from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome # Icons font awesome v4

from imgui_bundle.immapp.immapp_utils import (
static as static,
Expand All @@ -46,6 +47,9 @@
SimpleRunnerParams as SimpleRunnerParams,
)


manual_render = _native_bundle.immapp_cpp.manual_render

__all__ = [
"clock_seconds",
"default_node_editor_context",
Expand All @@ -69,6 +73,7 @@
"RunnerParams",
"SimpleRunnerParams",
"snippets",
"manual_render",
"begin_plot_in_node_editor",
"end_plot_in_node_editor",
"show_resizable_plot_in_node_editor",
Expand Down
1 change: 1 addition & 0 deletions bindings/imgui_bundle/immapp/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ from .immapp_cpp import (
run_with_markdown as run_with_markdown,
AddOnsParams as AddOnsParams,
snippets as snippets,
manual_render as manual_render,
begin_plot_in_node_editor as begin_plot_in_node_editor,
end_plot_in_node_editor as end_plot_in_node_editor,
show_resizable_plot_in_node_editor as show_resizable_plot_in_node_editor,
Expand Down
81 changes: 80 additions & 1 deletion bindings/imgui_bundle/immapp/immapp_cpp.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,87 @@ def delete_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> None:
pass

# #endif
# }
#

# =========================== HelloImGui::ManualRender ==================================
# @@md#HelloImGui::ManualRender

# @@md

# <submodule manual_render>
class manual_render: # Proxy class that introduces typings for the *submodule* manual_render
pass # (This corresponds to a C++ namespace. All method are static!)
""" namespace ManualRender"""
# Immapp::ManualRender is a namespace that groups functions, allowing fine-grained control over the rendering process:
# - It is customizable like Immapp::Run: initialize it with `RunnerParams` and `AddOnsParams`.
# - `ManualRender::Render()` will render the application for one frame:
# - Ensure that `ManualRender::Render()` is triggered regularly (e.g., through a loop or other mechanism)
# to maintain responsiveness. This method must be called on the main thread.

@staticmethod
def setup_from_runner_params(
runner_params: HelloImGui.RunnerParams,
add_ons_params: Optional[AddOnsParams] = None,
) -> None:
"""Initializes the rendering with the full customizable `RunnerParams`.
This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
A distinct copy of `RunnerParams` is stored internally.
---
Python bindings defaults:
If addOnsParams is None, then its default value will be: AddOnsParams()
"""
pass

@staticmethod
def setup_from_simple_runner_params(
simple_params: HelloImGui.SimpleRunnerParams,
add_ons_params: Optional[AddOnsParams] = None,
) -> None:
"""Initializes the rendering with `SimpleRunnerParams`.
This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
---
Python bindings defaults:
If addOnsParams is None, then its default value will be: AddOnsParams()
"""
pass

@staticmethod
def setup_from_gui_function(
gui_function: VoidFunction,
window_title: str = "",
window_size_auto: bool = False,
window_restore_previous_geometry: bool = False,
window_size: Optional[ScreenSize] = None,
fps_idle: float = 10.0,
with_implot: bool = False,
with_markdown: bool = False,
with_node_editor: bool = False,
with_tex_inspect: bool = False,
with_node_editor_config: Optional[NodeEditorConfig] = None,
with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
) -> None:
"""Initializes the renderer with a simple GUI function and additional parameters.
This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
---
Python bindings defaults:
If windowSize is None, then its default value will be: DefaultWindowSize
"""
pass

@staticmethod
def render() -> None:
"""Renders the current frame. Should be called regularly to maintain the application's responsiveness."""
pass

@staticmethod
def tear_down() -> None:
"""Tears down the renderer and releases all associated resources.
This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
After calling `TearDown()`, the InitFromXXX can be called with new parameters.
"""
pass

# </submodule manual_render>
#################### </generated_from:runner.h> ####################

#################### <generated_from:clock.h> ####################
Expand Down
74 changes: 73 additions & 1 deletion external/immapp/bindings/pybind_immapp_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,79 @@ void py_init_module_immapp_cpp(nb::module_& m)
nb::arg("runner_params"),
"DeleteNodeEditorSettings deletes the json file for the node editor settings.");
// #endif
// }
//

{ // <namespace ManualRender>
nb::module_ pyNsManualRender = m.def_submodule("manual_render", "namespace ManualRender");
pyNsManualRender.def("setup_from_runner_params",
[](const HelloImGui::RunnerParams & runnerParams, const std::optional<const ImmApp::AddOnsParams> & addOnsParams = std::nullopt)
{
auto SetupFromRunnerParams_adapt_mutable_param_with_default_value = [](const HelloImGui::RunnerParams & runnerParams, const std::optional<const ImmApp::AddOnsParams> & addOnsParams = std::nullopt)
{

const ImmApp::AddOnsParams& addOnsParams_or_default = [&]() -> const ImmApp::AddOnsParams {
if (addOnsParams.has_value())
return addOnsParams.value();
else
return ImmApp::AddOnsParams();
}();

ImmApp::ManualRender::SetupFromRunnerParams(runnerParams, addOnsParams_or_default);
};

SetupFromRunnerParams_adapt_mutable_param_with_default_value(runnerParams, addOnsParams);
},
nb::arg("runner_params"), nb::arg("add_ons_params") = nb::none(),
" Initializes the rendering with the full customizable `RunnerParams`.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n A distinct copy of `RunnerParams` is stored internally.\n---\nPython bindings defaults:\n If addOnsParams is None, then its default value will be: AddOnsParams()");

pyNsManualRender.def("setup_from_simple_runner_params",
[](const HelloImGui::SimpleRunnerParams & simpleParams, const std::optional<const ImmApp::AddOnsParams> & addOnsParams = std::nullopt)
{
auto SetupFromSimpleRunnerParams_adapt_mutable_param_with_default_value = [](const HelloImGui::SimpleRunnerParams & simpleParams, const std::optional<const ImmApp::AddOnsParams> & addOnsParams = std::nullopt)
{

const ImmApp::AddOnsParams& addOnsParams_or_default = [&]() -> const ImmApp::AddOnsParams {
if (addOnsParams.has_value())
return addOnsParams.value();
else
return ImmApp::AddOnsParams();
}();

ImmApp::ManualRender::SetupFromSimpleRunnerParams(simpleParams, addOnsParams_or_default);
};

SetupFromSimpleRunnerParams_adapt_mutable_param_with_default_value(simpleParams, addOnsParams);
},
nb::arg("simple_params"), nb::arg("add_ons_params") = nb::none(),
" Initializes the rendering with `SimpleRunnerParams`.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n---\nPython bindings defaults:\n If addOnsParams is None, then its default value will be: AddOnsParams()");

pyNsManualRender.def("setup_from_gui_function",
[](const VoidFunction & guiFunction, const std::string & windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const std::optional<const ScreenSize> & windowSize = std::nullopt, float fpsIdle = 10.f, bool withImplot = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, const std::optional<NodeEditorConfig> & withNodeEditorConfig = std::nullopt, const std::optional<ImGuiMd::MarkdownOptions> & withMarkdownOptions = std::nullopt)
{
auto SetupFromGuiFunction_adapt_mutable_param_with_default_value = [](const VoidFunction & guiFunction, const std::string & windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const std::optional<const ScreenSize> & windowSize = std::nullopt, float fpsIdle = 10.f, bool withImplot = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, const std::optional<NodeEditorConfig> & withNodeEditorConfig = std::nullopt, const std::optional<ImGuiMd::MarkdownOptions> & withMarkdownOptions = std::nullopt)
{

const ScreenSize& windowSize_or_default = [&]() -> const ScreenSize {
if (windowSize.has_value())
return windowSize.value();
else
return DefaultWindowSize;
}();

ImmApp::ManualRender::SetupFromGuiFunction(guiFunction, windowTitle, windowSizeAuto, windowRestorePreviousGeometry, windowSize_or_default, fpsIdle, withImplot, withMarkdown, withNodeEditor, withTexInspect, withNodeEditorConfig, withMarkdownOptions);
};

SetupFromGuiFunction_adapt_mutable_param_with_default_value(guiFunction, windowTitle, windowSizeAuto, windowRestorePreviousGeometry, windowSize, fpsIdle, withImplot, withMarkdown, withNodeEditor, withTexInspect, withNodeEditorConfig, withMarkdownOptions);
},
nb::arg("gui_function"), nb::arg("window_title") = "", nb::arg("window_size_auto") = false, nb::arg("window_restore_previous_geometry") = false, nb::arg("window_size") = nb::none(), nb::arg("fps_idle") = 10.f, nb::arg("with_implot") = false, nb::arg("with_markdown") = false, nb::arg("with_node_editor") = false, nb::arg("with_tex_inspect") = false, nb::arg("with_node_editor_config") = nb::none(), nb::arg("with_markdown_options") = nb::none(),
" Initializes the renderer with a simple GUI function and additional parameters.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n---\nPython bindings defaults:\n If windowSize is None, then its default value will be: DefaultWindowSize");

pyNsManualRender.def("render",
ImmApp::ManualRender::Render, "Renders the current frame. Should be called regularly to maintain the application's responsiveness.");

pyNsManualRender.def("tear_down",
ImmApp::ManualRender::TearDown, " Tears down the renderer and releases all associated resources.\n This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n After calling `TearDown()`, the InitFromXXX can be called with new parameters.");
} // </namespace ManualRender>
//////////////////// </generated_from:runner.h> ////////////////////


Expand Down
Loading

0 comments on commit b7a73b2

Please sign in to comment.