Skip to content

Commit

Permalink
idling: add timeActiveAfterLastEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Apr 29, 2024
1 parent 716180b commit 4ca635a
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,10 +978,19 @@ void AbstractRunner::CreateFramesAndRender()
{ // SCOPED_RELEASE_GIL_ON_MAIN_THREAD start
SCOPED_RELEASE_GIL_ON_MAIN_THREAD;

// Keep track of the time of the last event,
// by counting the number of events in the input queue
static double timeLastEvent = -1.;
int nbEventsBefore = ImGui::GetCurrentContext()->InputEventsQueue.size();
// If the last event is recent, do not idle
double now = ImGui::GetTime();
bool preventIdling = (timeLastEvent > 0.) && (now - timeLastEvent < (double)params.fpsIdling.timeActiveAfterLastEvent);

#ifndef __EMSCRIPTEN__
// Idling for non emscripten, where HelloImGui is responsible for the main loop.
// This form of idling will call WaitForEventTimeout(), which may call sleep():
IdleBySleeping();
if (!preventIdling)
IdleBySleeping();
#endif

// Poll Events (this fills GImGui.InputEventsQueue)
Expand All @@ -990,12 +999,17 @@ void AbstractRunner::CreateFramesAndRender()
#ifdef __EMSCRIPTEN__
// Idling for emscripten: early exit if idling
// This test should be done after calling Impl_PollEvents() since it checks the event queue for incoming events!
if (ShallIdleThisFrame_Emscripten())
if ( ! preventIdling && ShallIdleThisFrame_Emscripten())
{
mIdxFrame += 1;
return;
}
#endif

int nbEventsAfter = ImGui::GetCurrentContext()->InputEventsQueue.size();
if (nbEventsAfter > nbEventsBefore)
timeLastEvent = ImGui::GetTime();

} // SCOPED_RELEASE_GIL_ON_MAIN_THREAD end

if (foldable_region) // Update frame rate stats
Expand Down Expand Up @@ -1076,7 +1090,7 @@ void AbstractRunner::CreateFramesAndRender()
// iii/ At the end of the second frame, we measure the size of the widgets and use it as the application window size, if the user required auto size
// ==> Note: RenderGui() may measure the size of the window and resize it if mIdxFrame==1
// RenderGui may call many user callbacks, so it should not be inside SCOPED_RELEASE_GIL_ON_MAIN_THREAD
RenderGui();
RenderGui();

if (params.callbacks.BeforeImGuiRender)
params.callbacks.BeforeImGuiRender();
Expand Down
4 changes: 4 additions & 0 deletions src/hello_imgui/runner_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ struct FpsIdling
// refresh needs)
float fpsIdle = 9.f;

// `timeActiveAfterLastEvent`: _float, default=3.f_.
// Time in seconds after the last event before the application is considered idling.
float timeActiveAfterLastEvent = 3.f;

// `enableIdling`: _bool, default=true_.
// Disable idling by setting this to false.
// (this can be changed dynamically during execution)
Expand Down

0 comments on commit 4ca635a

Please sign in to comment.