Skip to content
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

Preparation work toward making Dear ImGui support multiple contexts used in parallel #5859

Closed
wants to merge 5 commits into from

Conversation

Dragnalith
Copy link
Contributor

Note
This PR is a subsidiary work regarding the main pull request to make Dear ImGui able to support multiple contexts (#5856). The detailed purpose of this initiative can be read in the main PR description.

This PR contains the first 5 commits of the #5856 pull request.

Goal

The goal of that PR is to refactor ImGui to make classes, memory allocator, and callback independent from implicit context.

# Purpose

This work has as small impact on the code base, but it has a big impact toward refactoring Dear ImGui to support multiple contexts, because it contains all the custom work required to make Dear ImGui support multiple contexts.

Remaining work even if big regarding the number of modifications, should be less risky because very predictable and straightforward.

Content

  • ImGuiIO, ImGuiWindow, ImGuiInputTextCallback, ImGuiListClipper, ImGuiTextFilter, ImGuiStackSize, and ImGuiTextInputState are refactored to be independent from the implicit context.
  • Clipboard and IME callback have been refactored to be independent from the implicit context
  • MemAlloc and MemFree have been refactored to be independent from the implicit context

Details are explained in commit messages.

--
This commit is a preparation toward adding ImGui apis with explicit context
and making ImGui applications being able to use multiple context at the same time
whatever their concurrency model.
--

This commit modifies ImGuiIO, ImGuiInputTextCallback, ImGuiListClipper
and ImGuiStackSize so those classes do not to depend on GImGui context
anymore.

About ImGuiIO:
- ImGuiIO depends on ImGuiContext because some of its method want to
  event to `g.InputEventQueue`.
- To make ImGuiIO aware of the context to use, context which creates the
  ImGuiIO is given as argument of ImGuiIO constructor.
- The assert `IM_ASSERT(&g.IO == this && "Can only add events to current context.")`
  has been removed since it does not make sense anymore

NOTE: ImGuiIO could be completely independent of ImGuiContext if the
InputEventQueue was moved from ImGuiContext to ImGuiIO, but since
ImGuiIO is a public class it would expose InputEvent type. Solving this
problem is out of the current scope, but it is interesting to notice.

About ImGuiInputTextCallback:
- ImGuiInputTextCallback depends on ImGuiContext because it has a
  `InsertChars` method adding character to `g.InputTextState`
- To make ImGuiInputTextCallback aware of which context to use, the
  appropriate context is given as argument of ImGuiInputTextCallback
  constructor.

About ImGuiListClipper:
- ImGuiListClipper apply to a context through its `Begin`, `End`, and `Step`
  method.
- To make ImGuiListClipper aware of which context to use, the
  appropriate context is given as argument of ImGuiListClipper
  constructor.
- Since the behavior is different than previously the class has been
  renamed ImGuiListClipperEx
- In order to preserve backward compatibility, a subclass of ImGuiListClipperEx
  named ImGuiListClipper has been defined and forward the implicit context
  to ImGuiListClipperEx parent.

About ImGuiTextFilter:
- ImGuiTextFilter depends on the implicit context because the Draw(..)
  method call ImGui::InputText(...)
- Instead from that commit the Draw(...) method takes an explicit context
  as first argument
- Since the behavior is different than previously the class has been
  renamed ImGuiTextFilterEx
- In order to preserve backward compatibility, a subclass of ImGuiTextFilterEx
  named ImGuiTextFilter has been defined. This subclass has a draw method
  override which and forward the implicit context to the parent class Draw(...)

About ImGuiStackSizes:
- ImGuiStackSizes was depending on ImGuiContext because of its
  `SetToCurrentState` and `CompareWithCurrentState` method
- ImGuiStackSizes is an helper object use
  for comparing state of context. It does not necessarily need to
  compare the same context. For that reason, as opposed to previous
  classes it takes the context it wants to compare to as argument of
  its method.
- For this occasion `SetToCurrentState` and `CompareWithCurrentState`
  have been renamed `SetToContextState` and `CompareWithContextState`
  to match the new method signature.
…Gui context

--
This commit is a preparation toward adding ImGui apis with explicit context
and making ImGui applications being able to use multiple context at the same time
whatever their concurrency model.
--

Prior to this commit ImGuiInputTextState::OnKeyPressed was depending on the
global context to know which font and font size to use, and if it should
follow MacOSX behaviors or not (c.f ConfigMacOSXBehaviors).

Instead of using the global context, this commit store the context as
attribute of ImGuiInputTextState. Since this state is forwarded to most
of text edit related function, it possible to access font, font size and
ConfigMacOSXBehaviors from everywhere.

NOTE: I have noticed a bug prior to that commit: if the font or font size
change while editing the same widget, the ImGuiInputTextState become invalid
and there is no code to handle this invalidation. Fixing this bug is out
of scope of current pull request.
… context

--
This commit is a preparation toward adding ImGui apis with explicit context
and making ImGui applications being able to use multiple context at the same time
whatever their concurrency model.
--

Even in a scenario where multiple ImGuiContext are active at the same time
ImGui::MemAlloc and ImGui::MemFree will still be global and context independent.

The implementation of ImGui::MemAlloc and ImGui::MemFree should not depend
on the ImGuiContext.

Prior to this commit, the implementation was depending on ImGuiContext to store
active allocation metrics. Instead this commit makes this metrics be an atomic
counter defined next to GImAllocatorAllocFunc and GImAllocatorUserData globals
--
This commit is a preparation toward adding ImGui apis with explicit context
and making ImGui applications being able to use multiple context at the same time
whatever their concurrency model.
--

Prior to this commit ImGui::StyleColorsDark, ImGui::StyleColorsLight,
and ImGui::StyleColorsClassic was depending on GImGui for their implementation.
It was a problem because ImGui::StyleColorsDark is used inside ImGuiStyle constructor,
making the ImGuiStyle class being dependent on ImGuiContext.

Instead, in this commit, those style setters functions have been split into two implementations:
- one with an ImGuiStyle* argument (e.g `StyleColorsDark(ImGuiStyle* dst)`)
- one with no argument (e.g `StyleColorsDark()`)

The version without argument exist for backward compatibility and depends
on GImGui context. The version with an ImGuiStyle* argument do not depend
on ImGuiContext anymore. That way ImGuiStyle constructor can safely call
StyleColorsDark(ImGuiStyle* dst) without implicit dependency on GImGui
…mGui

--
This commit is a preparation toward adding ImGui apis with explicit context
and making ImGui applications being able to use multiple context at the same time
whatever their concurrency model.
--

Prior to this commit `GetClipboardTextFn_DefaultImpl` on windows was depending
on the global GImGui context.
Instead this commit is forwarding the ImGuiContext as user data.

Prior to this commit `SetPlatformImeDataFn_DefaultImpl` on windows was depending
on the global GImGui context through a call to ImGui::GetIO().ImeWindowHandle.
The call has been remove, and ImeWindowHandle is forwarded by setting
ImGuiViewport::PlatformHandleRaw to ImeWindowHandle when PlatformHandleRaw
is null.
@Dragnalith Dragnalith changed the title Preparation to make Dear ImGui support multiple contexts used in parallel Preparation work toward making Dear ImGui support multiple contexts used in parallel Nov 5, 2022
@Dragnalith Dragnalith closed this Nov 5, 2022
@Dragnalith Dragnalith deleted the pre_explicit_context branch November 22, 2023 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant