r5sdk/r5dev/gameui/imgui_system.h
Kawe Mazidjatari 85c7db410d ImguiSystem: properly implement ImGui and fix several bugs
Moved implementation to dedicated class 'CImguiSystem' with the following changes:

* Added mutex for ImGui_ImplWin32_WndProcHandler(), the window proc is ran from a different thread than CImguiSystem::SampleFrame() is being called from. Needs a mutex as both functions interact with the input queue list.

* Added init stages for debugging and preventing the system from running certain parts of the code if a certain stage hasn't been reached yet.

* NULL out ImGuiContext::ConfigNavWindowingKeyNext , we don't need any nav window shortcuts as users don't need then in-game, and it also interferes with certain key binds some users have.

* CImguiSystem::SampleFrame() (previously ImguiSystem_SampleFrame()), is now being called from CMaterialSystem::SwapBuffers(), as that function is called from the main thread while also getting updated during level loads/etc, so instead of switching between 2 static buffers for as long as the levels are being loaded, we imgui updates properly too and directly swap afterwards.

* Removed hack in CGame::WindowProc() where we would only run windowproc if we aren't shutting the game down. This was needed as there was a chance of a crash at some rare cases, but this was simply due to a missing mutex which has been addressed and fixed as of this commit.

* Lock mutex during init and shutdown.
2024-04-05 18:19:39 +02:00

68 lines
1.7 KiB
C++

//=============================================================================//
//
// Purpose: Dear ImGui engine implementation
//
//=============================================================================//
#ifndef IMGUI_SYSTEM_H
#define IMGUI_SYSTEM_H
#include "imgui/misc/imgui_snapshot.h"
class CImguiSystem
{
public:
CImguiSystem();
bool Init();
void Shutdown();
void SwapBuffers();
void SampleFrame();
void RenderFrame();
// statics:
static LRESULT MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
// inlines:
inline bool IsInitialized() const
{
return m_systemInitState >= ImguiSystemInitStage_e::IM_SYSTEM_INIT;
};
private:
enum class ImguiSystemInitStage_e
{
// When the system failed to initialize, the stage would be set to
// this.
IM_INIT_FAILURE = -1,
IM_PENDING_INIT,
IM_SYSTEM_INIT,
// State gets set to this when the first frame has been sampled.
IM_FRAME_SAMPLED,
// State gets set to this then buffers have been swapped for the first
// time.
IM_FRAME_SWAPPED
};
ImguiSystemInitStage_e m_systemInitState;
ImDrawDataSnapshot m_snapshotData;
// Mutex used during swapping and rendering, we draw the windows in the
// main thread, and render it in the render thread. The only place this
// mutex is used is during snapshot swapping and during rendering
mutable CThreadFastMutex m_snapshotBufferMutex;
// Mutex used between ImGui window procedure handling and drawing, see
// https://github.com/ocornut/imgui/issues/6895. In this engine the window
// is ran in thread separate from the main thread, therefore it needs a
// lock to control access as main calls SampleFrame().
mutable CThreadFastMutex m_inputEventQueueMutex;
};
CImguiSystem* ImguiSystem();
#endif // IMGUI_SYSTEM_H