Stiffstream / sobjectizer

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.
https://stiffstream.com/en/products/sobjectizer.html
Other
476 stars 47 forks source link

Integrating with GUI applications #83

Open prabuinet opened 1 month ago

prabuinet commented 1 month ago

It will be helpful if someone drop an example on how to integerate this with a GUI app (for example IMGUI).

Any pointers or links will also be fine.

I believe it has to do something with the main loop: ... [below is example of imgui/sdl2 main loop]

    // Main loop
    bool done = false;
    while (!done)
    {
        // Poll and handle events (inputs, window resize, etc.)
        // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
        // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
        // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
        // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                done = true;
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
                done = true;
        }
        if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
        {
            SDL_Delay(10);
            continue;
        }

        // Resize swap chain?
        int fb_width, fb_height;
        SDL_GetWindowSize(window, &fb_width, &fb_height);
        if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
        {
            ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
            ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
            g_MainWindowData.FrameIndex = 0;
            g_SwapChainRebuild = false;
        }

Thanks

eao197 commented 1 month ago

Hi!

It depends on what do you want to have.

If you want to run your agents on a separate work thread then it's enough to use so_5::wrapped_env_t before your GUI-handling loop. Something like that:

so_5::wrapped_env_t sobjectizer{ ... };
bool done = false;
while (!done)
{
    ... // Handling of GUI events and refreshing UI
}

If you need to send some information from your agents to the main thread, then mchains can be used:

so_5::wrapped_env_t sobjectizer{...};
auto data_mchain = so_5::create_mchain(sobjectizer);
... // Registration of some agents and passing data_mchain to them.

bool done = false;
while (!done)
{
    // Reading data from mchain.
    so_5::receive(so_5::from(data_mchain).total_time(5ms), ...);

    ... // Handling of GUI events and refreshing UI
}

If you want to run your agents on the main thread it's also possible, but requires a special dispatcher implementation that will contain main GUI-loop inside.