Fixed hot-reloading issues. Hot-reloading may be useful when developing this plug-in but it doesn't play well with free functions used in ImGui interface (limitation of the system I guess). Switched to a custom GImGui which after hot-reload can be redirected to a new module. This fixes a crash caused by GImGui in obsolete module pointing to released resources and guarantees that ImGui code remains functional.

This commit is contained in:
Sebastian 2018-08-10 23:53:03 +01:00
parent 20a7675787
commit 74c794b53e
4 changed files with 61 additions and 0 deletions

View File

@ -15,6 +15,15 @@
#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
#endif // PLATFORM_XBOXONE
#if WITH_EDITOR
// Global ImGui context pointer.
ImGuiContext* GImGuiContextPtr = nullptr;
// Handle to the global ImGui context pointer.
ImGuiContext** GImGuiContextPtrHandle = &GImGuiContextPtr;
// Get the global ImGui context pointer (GImGui) indirectly to allow redirections in obsolete modules.
#define GImGui (*GImGuiContextPtrHandle)
#endif // WITH_EDITOR
#if PLATFORM_WINDOWS
#include <AllowWindowsPlatformTypes.h>
#endif // PLATFORM_WINDOWS
@ -51,4 +60,16 @@ namespace ImGuiImplementation
return false;
}
}
#if WITH_EDITOR
ImGuiContext** GetImGuiContextHandle()
{
return GImGuiContextPtrHandle;
}
void SetImGuiContextHandle(ImGuiContext** Handle)
{
GImGuiContextPtrHandle = Handle;
}
#endif // WITH_EDITOR
}

View File

@ -10,4 +10,12 @@ namespace ImGuiImplementation
{
// Get specific cursor data.
bool GetCursorData(ImGuiMouseCursor CursorType, FVector2D& OutSize, FVector2D& OutUVMin, FVector2D& OutUVMax, FVector2D& OutOutlineUVMin, FVector2D& OutOutlineUVMax);
#if WITH_EDITOR
// Get the handle to the ImGui Context pointer.
ImGuiContext** GetImGuiContextHandle();
// Set the ImGui Context pointer handle.
void SetImGuiContextHandle(ImGuiContext** Handle);
#endif // WITH_EDITOR
}

View File

@ -7,6 +7,7 @@
#include "Utilities/WorldContextIndex.h"
#if WITH_EDITOR
#include "ImGuiImplementation.h"
#include "Editor/ImGuiEditor.h"
#endif
@ -138,7 +139,32 @@ void FImGuiModule::ShutdownModule()
checkf(ImGuiModuleManager, TEXT("Null ImGui Module Manager. Module manager instance should be deleted during module shutdown."));
delete ImGuiModuleManager;
ImGuiModuleManager = nullptr;
#if WITH_EDITOR
// When shutting down we leave the global ImGui context pointer and handle pointing to resources that are already
// deleted. This can cause troubles after hot-reload when code in other modules calls ImGui interface functions
// which are statically bound to the obsolete module. To keep ImGui code functional we can redirect context handle
// to point to the new module.
FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
{
if (Reason == EModuleChangeReason::ModuleLoaded && Name == "ImGui")
{
FImGuiModule& LoadedModule = FImGuiModule::Get();
if (&LoadedModule != this)
{
ImGuiImplementation::SetImGuiContextHandle(LoadedModule.GetImGuiContextHandle());
}
}
});
#endif // WITH_EDITOR
}
#if WITH_EDITOR
ImGuiContext** FImGuiModule::GetImGuiContextHandle()
{
return ImGuiImplementation::GetImGuiContextHandle();
}
#endif
bool FImGuiModule::IsInputMode() const
{

View File

@ -110,4 +110,10 @@ public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
#if WITH_EDITOR
virtual struct ImGuiContext** GetImGuiContextHandle();
#endif
};