Skip to content

A template for multithreading? (GUI & Worker) #9539

Description

@LRDPRDX

Version/Branch of Dear ImGui:

Version (head): 39e7bf5, Branch: master

Back-ends:

imgui_impl_sdl2.cpp + imgui_impl_opengl2.cpp

Compiler, OS:

Linux + GCC

Full config/build information:

Dear ImGui 1.92.8 WIP (19272)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201103
define: __linux__
define: __GNUC__=13
IM_ASSERT: runs expression: OK. expand size: OK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2 (2.30.0, 2.30.0)
io.BackendRendererName: imgui_impl_opengl2
io.ConfigFlags: 0x00000003
 NavEnableKeyboard
 NavEnableGamepad
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00000016
 HasMouseCursors
 HasSetMousePos
 RendererHasTextures
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,128
io.Fonts->FontLoaderName: stb_truetype
io.DisplaySize: 1906.00,1048.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

Dear Community,

First of all sorry for yet another question about multithreading. I have read several (maybe not all) similar (at least at first sight) issues but I didn't find anything which I could find helpful.

My task is simple. I have GUI to control and read some hardware (a microcontroller). Now everything is done in one thread, so one can see in the code:

    if(auto state = t.state(); state == t5::EState_t::eIdle)
    {
        if(axis.mode == Axis::EMode_t::eRelative)
        {
            if(ImGui::Button(axis.icons.left.c_str(), { 0, 0 }))
                t.go(axis.axis, t5::EDir_t::eCW, axis.steps.target);
            ImGui::SameLine();
            if(ImGui::Button(axis.icons.right.c_str(), { 0, 0 }))
                t.go(axis.axis, t5::EDir_t::eCCW, axis.steps.target);
        }
        else
        {
            if(ImGui::Button("Go"))
                t.go2(axis.axis, axis.steps.target);
        }
    }

all of those member-function calls of the object t are actual communications to the microcontroller. Now everything is working fine (though FPS is 20-22) and it doesn't feel freezing or lagging. However, I would like to split somehow the part of reading / writing to the uC and actually displaying the GUI. I don't quite understand what is the design it should be ? More over, I have a long running tasks like caibration. And I want to display the progress, for example. So the only one way that comes to my mind is like having a proxy object (protected by a mutex) (or objects in a queue) which would represent a state of my uC (current positions, moving or idleing, etc) and also a queue of commands (also protected) (which means writing to the uC). Then one thread (the worker) is the only thread which has the actual access to the device, communicates with it according to the command queue, and fills the proxy object (locking the mutex before). Then in the GUI (main) thread we read the proxy object and fill the GUI dynamic widgets (like labels and plots) (also locking the mutex before).

Is this approach natural or I must learn more about the imGui internals to do it ? Because I see people more asking about two different threads like rendering and the rest, but not about ubiquitous "Worker & GUI" case.

Thank you in advance !

Screenshots/Video:

Image

Minimal, Complete and Verifiable Example code:

Don't think I have something for this type of issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions