Skip to content

Commit

Permalink
First work / imgui test engine integration
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Sep 27, 2023
1 parent 7e88825 commit c5c42f2
Show file tree
Hide file tree
Showing 12 changed files with 532 additions and 6 deletions.
26 changes: 24 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ endif()
project(HelloImGui LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)


###############################################################################
# hello_imgui_add_app location
###############################################################################
Expand Down Expand Up @@ -88,6 +89,12 @@ else()
option(HELLOIMGUI_BUILD_TESTS "Build tests" OFF)
endif()

#------------------------------------------------------------------------------
# Options / ImGui Test Engine
#------------------------------------------------------------------------------
option(HELLOIMGUI_WITH_TEST_ENGINE "Provide ImGui Test engine" OFF)
set(IMGUI_TEST_ENGINE_BASEPATH ${CMAKE_CURRENT_LIST_DIR}/../imgui_test_engine CACHE STRING "path to imgui_test_engine")

#------------------------------------------------------------------------------
# Esmcripten build options
#------------------------------------------------------------------------------
Expand Down Expand Up @@ -136,7 +143,13 @@ option(HELLOIMGUI_USE_GLAD "Use Glad OpenGl loader" ${need_opengl_loader})
###############################################################################


###############################################################################
# HelloImGui Build Actions
###############################################################################

#------------------------------------------------------------------------------
# use SDL for emscripten
#------------------------------------------------------------------------------
if (EMSCRIPTEN AND NOT HELLOIMGUI_USE_SDL_OPENGL3 AND NOT HELLOIMGUI_USE_GLFW_OPENGL3)
set(HELLOIMGUI_USE_SDL_OPENGL3 ON)
endif()
Expand Down Expand Up @@ -191,9 +204,10 @@ if (MSVC)
endif()


#------------------------------------------------------------------------------
# Main build actions
#------------------------------------------------------------------------------
set(HELLOIMGUI_BASEPATH ${CMAKE_CURRENT_LIST_DIR} CACHE STRING "Hello imgui base path" FORCE)


include(cmake/StandardProjectSettings.cmake)
include(cmake/StaticAnalyzers.cmake)
include(msvc/msvc_target_group)
Expand All @@ -207,6 +221,14 @@ endif()
add_subdirectory(external)
add_subdirectory(src)

#------------------------------------------------------------------------------
# imgui_test_engine integration
#------------------------------------------------------------------------------
if (HELLOIMGUI_WITH_TEST_ENGINE)
include(${CMAKE_CURRENT_LIST_DIR}/src/hello_imgui_test_engine_integration/hello_imgui_test_engine_cmake.cmake)
add_imgui_test_engine()
endif()

# Install
if(PROJECT_IS_TOP_LEVEL)
install(DIRECTORY hello_imgui_cmake DESTINATION .)
Expand Down
11 changes: 9 additions & 2 deletions src/hello_imgui/hello_imgui_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,21 @@ See [runner_callbacks.h](runner_callbacks.h).
You can here add a function that will be called once before exiting (when OpenGL and ImGui are
still inited)

* `PreNewFrame`: *VoidFunction, default=empty*.
* `BeforeExit_PostCleanup`: *VoidFunction, default=empty*.
You can here add a function that will be called once before exiting (after OpenGL and ImGui have been deinited)

* `PreNewFrame`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, and before the call to ImGui::NewFrame().
It is a good place to dynamically add new fonts, or dynamically add new dockable windows.

* `BeforeImGuiRender`: *VoidFunction, default=empty*.
* `BeforeImGuiRender`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, after the user Gui code,
and just before the call to ImGui::Render() (which will also call ImGui::EndFrame()).

* `AfterSwap`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, after the Gui was rendered
and swapped to the screen.

* `AnyBackendEventCallback`: *AnyBackendCallback, default=empty*.
Callbacks for events from a specific backend. _Only implemented for SDL, where the event
will be of type 'SDL_Event *'_
Expand Down
13 changes: 13 additions & 0 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#include "hello_imgui/internal/imgui_global_context.h" // must be included before imgui_internal.h
#include "imgui_internal.h"

#ifdef HELLOIMGUI_WITH_TEST_ENGINE
#include "hello_imgui_test_engine_integration/test_engine_integration.h"
#endif

#include <chrono>
#include <cassert>
#include <fstream>
Expand Down Expand Up @@ -328,6 +332,10 @@ void AbstractRunner::LayoutSettings_Save()

void AbstractRunner::Setup()
{
#ifdef HELLOIMGUI_WITH_TEST_ENGINE
_AddTestEngineCallbacks(&this->params);
#endif

Impl_InitBackend();
Impl_Select_Gl_Version();

Expand Down Expand Up @@ -579,6 +587,9 @@ void AbstractRunner::CreateFramesAndRender()

Impl_SwapBuffers();

if (params.callbacks.AfterSwap)
params.callbacks.AfterSwap();

if (foundPotentialFontLoadingError)
ReloadFontIfFailed();

Expand Down Expand Up @@ -695,6 +706,8 @@ void AbstractRunner::TearDown(bool gotException)
if (params.callbacks.BeforeExit)
params.callbacks.BeforeExit();
Impl_Cleanup();
if (params.callbacks.BeforeExit_PostCleanup)
params.callbacks.BeforeExit_PostCleanup();
}


Expand Down
15 changes: 13 additions & 2 deletions src/hello_imgui/runner_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,21 @@ struct MobileCallbacks
You can here add a function that will be called once before exiting (when OpenGL and ImGui are
still inited)
* `PreNewFrame`: *VoidFunction, default=empty*.
* `BeforeExit_PostCleanup`: *VoidFunction, default=empty*.
You can here add a function that will be called once before exiting (after OpenGL and ImGui have been deinited)
* `PreNewFrame`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, and before the call to ImGui::NewFrame().
It is a good place to dynamically add new fonts, or dynamically add new dockable windows.
* `BeforeImGuiRender`: *VoidFunction, default=empty*.
* `BeforeImGuiRender`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, after the user Gui code,
and just before the call to ImGui::Render() (which will also call ImGui::EndFrame()).
* `AfterSwap`: *VoidFunction, default=empty*.
You can here add a function that will be called at each frame, after the Gui was rendered
and swapped to the screen.
* `AnyBackendEventCallback`: *AnyBackendCallback, default=empty*.
Callbacks for events from a specific backend. _Only implemented for SDL, where the event
will be of type 'SDL_Event *'_
Expand Down Expand Up @@ -143,10 +150,14 @@ struct RunnerCallbacks
VoidFunction ShowMenus = EmptyVoidFunction();
VoidFunction ShowAppMenuItems = EmptyVoidFunction();
VoidFunction ShowStatus = EmptyVoidFunction();

VoidFunction PostInit = EmptyVoidFunction();
VoidFunction BeforeExit = EmptyVoidFunction();
VoidFunction BeforeExit_PostCleanup = EmptyVoidFunction();

VoidFunction PreNewFrame = EmptyVoidFunction();
VoidFunction BeforeImGuiRender = EmptyVoidFunction();
VoidFunction AfterSwap = EmptyVoidFunction();

AnyEventCallback AnyBackendEventCallback = EmptyEventCallback();

Expand Down
1 change: 1 addition & 0 deletions src/hello_imgui_demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(subdirs
hello_world
hello_globe
hello_idbfs
hello_imgui_demo_test_engine
)
foreach(target_name ${subdirs})
add_subdirectory(${target_name})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include(hello_imgui_add_app)
hello_imgui_add_app(hello_imgui_demo_test_engine hello_imgui_demo_test_engine.main.cpp)
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "hello_imgui/hello_imgui.h"

#ifdef HELLOIMGUI_WITH_TEST_ENGINE

#include "imgui_test_engine/imgui_te_context.h"
#include "imgui_test_engine/imgui_te_ui.h"
#include "imgui_test_engine/imgui_capture_tool.h"
#include "hello_imgui_test_engine_integration/test_engine_integration.h"


void RegisterAppMinimalTests(ImGuiTestEngine* e)
{
ImGuiTest* t = NULL;

//-----------------------------------------------------------------
// ## Demo Test: Use variables to communicate data between GuiFunc and TestFunc
//-----------------------------------------------------------------

t = IM_REGISTER_TEST(e, "demo_tests", "test2");
struct TestVars2 { int MyInt = 42; };
t->SetVarsDataType<TestVars2>();
t->GuiFunc = [](ImGuiTestContext* ctx)
{
TestVars2& vars = ctx->GetVars<TestVars2>();
ImGui::Begin("Test Window", NULL, ImGuiWindowFlags_NoSavedSettings);
ImGui::SliderInt("Slider", &vars.MyInt, 0, 1000);
ImGui::End();
};
t->TestFunc = [](ImGuiTestContext* ctx)
{
TestVars2& vars = ctx->GetVars<TestVars2>();
ctx->SetRef("Test Window");

IM_CHECK_EQ(vars.MyInt, 42);
ctx->ItemInputValue("Slider", 123);
IM_CHECK_EQ(vars.MyInt, 123);
};

//-----------------------------------------------------------------
// ## Open Metrics window
//-----------------------------------------------------------------

t = IM_REGISTER_TEST(e, "demo_tests", "open_metrics");
t->TestFunc = [](ImGuiTestContext* ctx)
{
ctx->SetRef("Dear ImGui Demo");
ctx->MenuCheck("Tools/Metrics\\/Debugger");
};

//-----------------------------------------------------------------
// ## Capture entire Dear ImGui Demo window.
//-----------------------------------------------------------------

t = IM_REGISTER_TEST(e, "demo_tests", "capture_screenshot");
t->TestFunc = [](ImGuiTestContext* ctx)
{
ctx->SetRef("Dear ImGui Demo");
ctx->ItemOpen("Widgets"); // Open collapsing header
ctx->ItemOpenAll("Basic"); // Open tree node and all its descendant
ctx->CaptureScreenshotWindow("Dear ImGui Demo", ImGuiCaptureFlags_StitchAll | ImGuiCaptureFlags_HideMouseCursor);
};

t = IM_REGISTER_TEST(e, "demo_tests", "capture_video");
t->TestFunc = [](ImGuiTestContext* ctx)
{
ctx->SetRef("Dear ImGui Demo");
ctx->ItemCloseAll("");
ctx->MouseTeleportToPos(ctx->GetWindowByRef("")->Pos);

ctx->CaptureAddWindow("Dear ImGui Demo"); // Optional: Capture single window
ctx->CaptureBeginVideo();
ctx->ItemOpen("Widgets");
ctx->ItemInputValue("Basic/input text", "My first video!");
ctx->CaptureEndVideo();
};


}

#endif


void Gui()
{
ImGui::Text("Hello");
//ImGui::ShowDemoWindow();
ImGuiTestEngine_ShowTestEngineWindows(HelloImGui::GetImGuiTestEngine(), NULL);

}


int main(int, char *[])
{
HelloImGui::RunnerParams runnerParams;
runnerParams.callbacks.ShowGui = Gui;

#ifdef HELLOIMGUI_WITH_TEST_ENGINE
runnerParams.callbacks.PostInit = [](){
RegisterAppMinimalTests(HelloImGui::GetImGuiTestEngine());
};
#endif

HelloImGui::Run(runnerParams);
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
if(POLICY CMP0079)
cmake_policy(SET CMP0079 NEW) # target_link_libraries() allows use with targets in other directories.
endif()


# Add imgui_test_engine lib with sources in imgui_test_engine/imgui_test_engine
function(_add_imgui_test_engine_lib)
set(source_folder ${IMGUI_TEST_ENGINE_BASEPATH}/imgui_test_engine)
file(GLOB_RECURSE sources ${source_folder}/*.h ${source_folder}/*.cpp)
add_library(imgui_test_engine ${sources})
target_include_directories(imgui_test_engine PUBLIC ${source_folder}/..)
endfunction()


# ImGui uses imconfig from imconfig_with_test_engine.h (with options for imgui_test_engine)
function(_configure_imgui_with_test_engine)
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="${CMAKE_CURRENT_FUNCTION_LIST_DIR}/imconfig_with_test_engine.h")
# Link imgui_test_engine with imgui
target_link_libraries(imgui_test_engine PUBLIC imgui)
# any App built with ImGui should now also link with imgui_test_engine
target_link_libraries(imgui PUBLIC imgui_test_engine)
endfunction()


# Add integration into HelloImGui
function(_add_hello_imgui_test_engine_integration)
target_compile_definitions(hello_imgui PUBLIC HELLOIMGUI_WITH_TEST_ENGINE)
target_sources(hello_imgui PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/test_engine_integration.cpp
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/test_engine_integration.h
)
target_include_directories(hello_imgui PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/..)
endfunction()


function(add_imgui_test_engine)
_add_imgui_test_engine_lib()
_configure_imgui_with_test_engine()
_add_hello_imgui_test_engine_integration()
endfunction()
Loading

0 comments on commit c5c42f2

Please sign in to comment.