mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-18 08:20:32 +00:00
Changed interface to register ImGui debug delegates:
- Added new FImGuiDelegates interface for ImGui debug delegates. - Added FImGuiDelegatesContainer for ImGui delegates. - Added code preserving delegates during hot-reloading and moving them to a new module. - Depreciated old FImGuiModule delegates interface and FImGuiDelegateHandle. - Delegates registered with depreciated interface are redirected and get benefit of being preserved during hot-reloading. This can be controlled with IMGUI_REDIRECT_OBSOLETE_DELEGATES. - Added IMGUI_WITH_OBSOLETE_DELEGATES allowing to strip depreciated interface from builds. - Modified context manager and context proxy to work with FImGuiDelegatesContainer.
This commit is contained in:
parent
2b5d871609
commit
867a34e640
@ -5,6 +5,13 @@ Versions marked as 'unofficial' are labelled only for the needs of this changelo
|
|||||||
Change History
|
Change History
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
Version: 1.15 (2019/04)
|
||||||
|
- Added new FImGuiDelegates interface for ImGui debug delegates.
|
||||||
|
- Added code preserving delegates during hot-reloading and moving them to a new module.
|
||||||
|
- DEPRECIATED old FImGuiModule delegates interface and FImGuiDelegateHandle.
|
||||||
|
- Delegates registered with depreciated interface are redirected and get benefit of being preserved during hot-reloading. This can be controlled with IMGUI_REDIRECT_OBSOLETE_DELEGATES.
|
||||||
|
- Added IMGUI_WITH_OBSOLETE_DELEGATES allowing to strip depreciated interface from builds (that interface will be officially removed in one of later releases).
|
||||||
|
|
||||||
Version: 1.14 (2019/03)
|
Version: 1.14 (2019/03)
|
||||||
- Added SImGuiLayout to resets layout for SImGuiWidget.
|
- Added SImGuiLayout to resets layout for SImGuiWidget.
|
||||||
- Refactored rendering in SImGuiWidget to take advantage of layout reset.
|
- Refactored rendering in SImGuiWidget to take advantage of layout reset.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 1,
|
"Version": 1,
|
||||||
"VersionName": "1.14",
|
"VersionName": "1.15",
|
||||||
"FriendlyName": "ImGui",
|
"FriendlyName": "ImGui",
|
||||||
"Description": "",
|
"Description": "",
|
||||||
"Category": "Debug",
|
"Category": "Debug",
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "ImGuiContextManager.h"
|
#include "ImGuiContextManager.h"
|
||||||
|
|
||||||
|
#include "ImGuiDelegatesContainer.h"
|
||||||
#include "ImGuiImplementation.h"
|
#include "ImGuiImplementation.h"
|
||||||
#include "Utilities/ScopeGuards.h"
|
#include "Utilities/ScopeGuards.h"
|
||||||
#include "Utilities/WorldContext.h"
|
#include "Utilities/WorldContext.h"
|
||||||
@ -89,6 +90,11 @@ void FImGuiContextManager::Tick(float DeltaSeconds)
|
|||||||
{
|
{
|
||||||
ContextData.ContextProxy.Tick(DeltaSeconds);
|
ContextData.ContextProxy.Tick(DeltaSeconds);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear to make sure that we don't store objects registered for world that is no longer valid.
|
||||||
|
FImGuiDelegatesContainer::Get().OnWorldDebug(Pair.Key).Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ private:
|
|||||||
{
|
{
|
||||||
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, int32 InPIEInstance = -1)
|
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, int32 InPIEInstance = -1)
|
||||||
: PIEInstance(InPIEInstance)
|
: PIEInstance(InPIEInstance)
|
||||||
, ContextProxy(ContextName, &SharedDrawEvent, &FontAtlas)
|
, ContextProxy(ContextName, ContextIndex, &SharedDrawEvent, &FontAtlas)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ private:
|
|||||||
struct FContextData
|
struct FContextData
|
||||||
{
|
{
|
||||||
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas)
|
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas)
|
||||||
: ContextProxy(ContextName, &SharedDrawEvent, &FontAtlas)
|
: ContextProxy(ContextName, ContextIndex, &SharedDrawEvent, &FontAtlas)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "ImGuiContextProxy.h"
|
#include "ImGuiContextProxy.h"
|
||||||
|
|
||||||
|
#include "ImGuiDelegatesContainer.h"
|
||||||
#include "ImGuiImplementation.h"
|
#include "ImGuiImplementation.h"
|
||||||
#include "ImGuiInteroperability.h"
|
#include "ImGuiInteroperability.h"
|
||||||
|
|
||||||
@ -52,8 +53,9 @@ FImGuiContextProxy::FImGuiContextPtr::~FImGuiContextPtr()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FImGuiContextProxy::FImGuiContextProxy(const FString& InName, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas)
|
FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas)
|
||||||
: Name(InName)
|
: Name(InName)
|
||||||
|
, ContextIndex(InContextIndex)
|
||||||
, SharedDrawEvent(InSharedDrawEvent)
|
, SharedDrawEvent(InSharedDrawEvent)
|
||||||
, IniFilename(TCHAR_TO_ANSI(*GetIniFile(InName)))
|
, IniFilename(TCHAR_TO_ANSI(*GetIniFile(InName)))
|
||||||
{
|
{
|
||||||
@ -91,22 +93,13 @@ void FImGuiContextProxy::Draw()
|
|||||||
|
|
||||||
// Broadcast draw event to allow listeners to draw their controls to this context.
|
// Broadcast draw event to allow listeners to draw their controls to this context.
|
||||||
#if DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
#if DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
||||||
if (DrawEvent.IsBound())
|
BroadcastWorldTick();
|
||||||
{
|
|
||||||
DrawEvent.Broadcast();
|
|
||||||
}
|
|
||||||
#endif // DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
#endif // DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
||||||
|
|
||||||
if (SharedDrawEvent && SharedDrawEvent->IsBound())
|
BroadcastMultiContextTick();
|
||||||
{
|
|
||||||
SharedDrawEvent->Broadcast();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
#if !DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
||||||
if (DrawEvent.IsBound())
|
BroadcastWorldTick();
|
||||||
{
|
|
||||||
DrawEvent.Broadcast();
|
|
||||||
}
|
|
||||||
#endif // !DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
#endif // !DRAW_EVENTS_ORDER_WORLD_BEFORE_MULTI_CONTEXT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,3 +185,34 @@ void FImGuiContextProxy::UpdateDrawData(ImDrawData* DrawData)
|
|||||||
DrawLists.Empty();
|
DrawLists.Empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FImGuiContextProxy::BroadcastWorldTick()
|
||||||
|
{
|
||||||
|
if (DrawEvent.IsBound())
|
||||||
|
{
|
||||||
|
DrawEvent.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ContextIndex != Utilities::INVALID_CONTEXT_INDEX)
|
||||||
|
{
|
||||||
|
FSimpleMulticastDelegate& WorldDebugEvent = FImGuiDelegatesContainer::Get().OnWorldDebug(ContextIndex);
|
||||||
|
if (WorldDebugEvent.IsBound())
|
||||||
|
{
|
||||||
|
WorldDebugEvent.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FImGuiContextProxy::BroadcastMultiContextTick()
|
||||||
|
{
|
||||||
|
if (SharedDrawEvent && SharedDrawEvent->IsBound())
|
||||||
|
{
|
||||||
|
SharedDrawEvent->Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
FSimpleMulticastDelegate& MultiContextDebugEvent = FImGuiDelegatesContainer::Get().OnMultiContextDebug();
|
||||||
|
if (MultiContextDebugEvent.IsBound())
|
||||||
|
{
|
||||||
|
MultiContextDebugEvent.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "ImGuiDrawData.h"
|
#include "ImGuiDrawData.h"
|
||||||
|
|
||||||
|
#include "Utilities/WorldContextIndex.h"
|
||||||
|
|
||||||
#include <ICursor.h>
|
#include <ICursor.h>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
@ -41,7 +43,7 @@ class FImGuiContextProxy
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FImGuiContextProxy(const FString& Name, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas);
|
FImGuiContextProxy(const FString& Name, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas);
|
||||||
|
|
||||||
FImGuiContextProxy(const FImGuiContextProxy&) = delete;
|
FImGuiContextProxy(const FImGuiContextProxy&) = delete;
|
||||||
FImGuiContextProxy& operator=(const FImGuiContextProxy&) = delete;
|
FImGuiContextProxy& operator=(const FImGuiContextProxy&) = delete;
|
||||||
@ -96,6 +98,9 @@ private:
|
|||||||
|
|
||||||
void UpdateDrawData(ImDrawData* DrawData);
|
void UpdateDrawData(ImDrawData* DrawData);
|
||||||
|
|
||||||
|
void BroadcastWorldTick();
|
||||||
|
void BroadcastMultiContextTick();
|
||||||
|
|
||||||
FImGuiContextPtr Context;
|
FImGuiContextPtr Context;
|
||||||
|
|
||||||
FVector2D DisplaySize = FVector2D::ZeroVector;
|
FVector2D DisplaySize = FVector2D::ZeroVector;
|
||||||
@ -115,6 +120,8 @@ private:
|
|||||||
|
|
||||||
TArray<FImGuiDrawList> DrawLists;
|
TArray<FImGuiDrawList> DrawLists;
|
||||||
|
|
||||||
|
int32 ContextIndex = Utilities::INVALID_CONTEXT_INDEX;
|
||||||
|
|
||||||
FString Name;
|
FString Name;
|
||||||
std::string IniFilename;
|
std::string IniFilename;
|
||||||
};
|
};
|
||||||
|
22
Source/ImGui/Private/ImGuiDelegates.cpp
Normal file
22
Source/ImGui/Private/ImGuiDelegates.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
|
||||||
|
|
||||||
|
#include "ImGuiPrivatePCH.h"
|
||||||
|
|
||||||
|
#include "ImGuiDelegates.h"
|
||||||
|
#include "ImGuiDelegatesContainer.h"
|
||||||
|
|
||||||
|
|
||||||
|
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug()
|
||||||
|
{
|
||||||
|
return OnWorldDebug(GWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug(UWorld* World)
|
||||||
|
{
|
||||||
|
return FImGuiDelegatesContainer::Get().OnWorldDebug(World);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSimpleMulticastDelegate& FImGuiDelegates::OnMultiContextDebug()
|
||||||
|
{
|
||||||
|
return FImGuiDelegatesContainer::Get().OnMultiContextDebug();
|
||||||
|
}
|
37
Source/ImGui/Private/ImGuiDelegatesContainer.cpp
Normal file
37
Source/ImGui/Private/ImGuiDelegatesContainer.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
|
||||||
|
|
||||||
|
#include "ImGuiPrivatePCH.h"
|
||||||
|
|
||||||
|
#include "ImGuiDelegatesContainer.h"
|
||||||
|
|
||||||
|
#include "Utilities/WorldContextIndex.h"
|
||||||
|
|
||||||
|
|
||||||
|
FImGuiDelegatesContainer FImGuiDelegatesContainer::DefaultInstance;
|
||||||
|
|
||||||
|
FImGuiDelegatesContainer* FImGuiDelegatesContainer::InstancePtr = &FImGuiDelegatesContainer::DefaultInstance;
|
||||||
|
|
||||||
|
void FImGuiDelegatesContainer::MoveContainer(FImGuiDelegatesContainer& Dst)
|
||||||
|
{
|
||||||
|
// Only move data if pointer points to default instance, otherwise our data has already been moved and we only
|
||||||
|
// keep pointer to a more recent version.
|
||||||
|
if (InstancePtr == &DefaultInstance)
|
||||||
|
{
|
||||||
|
Dst = MoveTemp(DefaultInstance);
|
||||||
|
DefaultInstance.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update pointer to the most recent version.
|
||||||
|
InstancePtr = &Dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSimpleMulticastDelegate& FImGuiDelegatesContainer::OnWorldDebug(UWorld* World)
|
||||||
|
{
|
||||||
|
return OnWorldDebug(Utilities::GetWorldContextIndex(*World));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FImGuiDelegatesContainer::Clear()
|
||||||
|
{
|
||||||
|
WorldDelegates.Empty();
|
||||||
|
MultiContextDelegate.Clear();
|
||||||
|
}
|
40
Source/ImGui/Private/ImGuiDelegatesContainer.h
Normal file
40
Source/ImGui/Private/ImGuiDelegatesContainer.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Containers/Map.h>
|
||||||
|
#include <Delegates/Delegate.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct FImGuiDelegatesContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Get the current instance (can change during hot-reloading).
|
||||||
|
static FImGuiDelegatesContainer& Get() { return *InstancePtr; }
|
||||||
|
|
||||||
|
// If this is an active container move its data to a destination and redirect all future calls to that instance.
|
||||||
|
static void MoveContainer(FImGuiDelegatesContainer& Dst);
|
||||||
|
|
||||||
|
// Get delegate to ImGui world debug event from known world instance.
|
||||||
|
FSimpleMulticastDelegate& OnWorldDebug(UWorld* World);
|
||||||
|
|
||||||
|
// Get delegate to ImGui world debug event from known context index.
|
||||||
|
FSimpleMulticastDelegate& OnWorldDebug(int32 ContextIndex) { return WorldDelegates.FindOrAdd(ContextIndex); }
|
||||||
|
|
||||||
|
// Get delegate to ImGui multi-context debug event.
|
||||||
|
FSimpleMulticastDelegate& OnMultiContextDebug() { return MultiContextDelegate; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
TMap<int32, FSimpleMulticastDelegate> WorldDelegates;
|
||||||
|
FSimpleMulticastDelegate MultiContextDelegate;
|
||||||
|
|
||||||
|
// Default container instance.
|
||||||
|
static FImGuiDelegatesContainer DefaultInstance;
|
||||||
|
|
||||||
|
// Pointer to the container instance that can be overwritten during hot-reloading.
|
||||||
|
static FImGuiDelegatesContainer* InstancePtr;
|
||||||
|
};
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "ImGuiModuleManager.h"
|
#include "ImGuiModuleManager.h"
|
||||||
|
|
||||||
|
#include "ImGuiDelegatesContainer.h"
|
||||||
#include "ImGuiTextureHandle.h"
|
#include "ImGuiTextureHandle.h"
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
#include "Utilities/WorldContext.h"
|
#include "Utilities/WorldContext.h"
|
||||||
@ -16,6 +17,8 @@
|
|||||||
|
|
||||||
#include <IPluginManager.h>
|
#include <IPluginManager.h>
|
||||||
|
|
||||||
|
#define IMGUI_REDIRECT_OBSOLETE_DELEGATES 1
|
||||||
|
|
||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "FImGuiModule"
|
#define LOCTEXT_NAMESPACE "FImGuiModule"
|
||||||
|
|
||||||
@ -38,18 +41,29 @@ static FImGuiModuleManager* ImGuiModuleManager = nullptr;
|
|||||||
static FImGuiEditor* ImGuiEditor = nullptr;
|
static FImGuiEditor* ImGuiEditor = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
FImGuiDelegateHandle FImGuiModule::AddEditorImGuiDelegate(const FImGuiDelegate& Delegate)
|
FImGuiDelegateHandle FImGuiModule::AddEditorImGuiDelegate(const FImGuiDelegate& Delegate)
|
||||||
{
|
{
|
||||||
|
#if IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
|
return { FImGuiDelegatesContainer::Get().OnWorldDebug(Utilities::EDITOR_CONTEXT_INDEX).Add(Delegate),
|
||||||
|
EDelegateCategory::Default, Utilities::EDITOR_CONTEXT_INDEX };
|
||||||
|
#else
|
||||||
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
||||||
|
|
||||||
return { ImGuiModuleManager->GetContextManager().GetEditorContextProxy().OnDraw().Add(Delegate),
|
return { ImGuiModuleManager->GetContextManager().GetEditorContextProxy().OnDraw().Add(Delegate),
|
||||||
EDelegateCategory::Default, Utilities::EDITOR_CONTEXT_INDEX };
|
EDelegateCategory::Default, Utilities::EDITOR_CONTEXT_INDEX };
|
||||||
|
#endif // IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FImGuiDelegateHandle FImGuiModule::AddWorldImGuiDelegate(const FImGuiDelegate& Delegate)
|
FImGuiDelegateHandle FImGuiModule::AddWorldImGuiDelegate(const FImGuiDelegate& Delegate)
|
||||||
{
|
{
|
||||||
|
#if IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
|
const int32 ContextIndex = Utilities::GetWorldContextIndex((UWorld*)GWorld);
|
||||||
|
return { FImGuiDelegatesContainer::Get().OnWorldDebug(ContextIndex).Add(Delegate), EDelegateCategory::Default, ContextIndex };
|
||||||
|
#else
|
||||||
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
@ -71,17 +85,32 @@ FImGuiDelegateHandle FImGuiModule::AddWorldImGuiDelegate(const FImGuiDelegate& D
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return{ Proxy.OnDraw().Add(Delegate), EDelegateCategory::Default, Index };
|
return{ Proxy.OnDraw().Add(Delegate), EDelegateCategory::Default, Index };
|
||||||
|
#endif // IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
}
|
}
|
||||||
|
|
||||||
FImGuiDelegateHandle FImGuiModule::AddMultiContextImGuiDelegate(const FImGuiDelegate& Delegate)
|
FImGuiDelegateHandle FImGuiModule::AddMultiContextImGuiDelegate(const FImGuiDelegate& Delegate)
|
||||||
{
|
{
|
||||||
|
#if IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
|
return { FImGuiDelegatesContainer::Get().OnMultiContextDebug().Add(Delegate), EDelegateCategory::MultiContext };
|
||||||
|
#else
|
||||||
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
||||||
|
|
||||||
return { ImGuiModuleManager->GetContextManager().OnDrawMultiContext().Add(Delegate), EDelegateCategory::MultiContext };
|
return { ImGuiModuleManager->GetContextManager().OnDrawMultiContext().Add(Delegate), EDelegateCategory::MultiContext };
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
|
void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
|
||||||
{
|
{
|
||||||
|
#if IMGUI_REDIRECT_OBSOLETE_DELEGATES
|
||||||
|
if (Handle.Category == EDelegateCategory::MultiContext)
|
||||||
|
{
|
||||||
|
FImGuiDelegatesContainer::Get().OnMultiContextDebug().Remove(Handle.Handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FImGuiDelegatesContainer::Get().OnWorldDebug(Handle.Index).Remove(Handle.Handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (ImGuiModuleManager)
|
if (ImGuiModuleManager)
|
||||||
{
|
{
|
||||||
if (Handle.Category == EDelegateCategory::MultiContext)
|
if (Handle.Category == EDelegateCategory::MultiContext)
|
||||||
@ -93,8 +122,11 @@ void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
|
|||||||
Proxy->OnDraw().Remove(Handle.Handle);
|
Proxy->OnDraw().Remove(Handle.Handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
|
||||||
FImGuiTextureHandle FImGuiModule::FindTextureHandle(const FName& Name)
|
FImGuiTextureHandle FImGuiModule::FindTextureHandle(const FName& Name)
|
||||||
{
|
{
|
||||||
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().FindTextureIndex(Name);
|
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().FindTextureIndex(Name);
|
||||||
@ -154,6 +186,10 @@ void FImGuiModule::ShutdownModule()
|
|||||||
// deleted. This can cause troubles after hot-reload when code in other modules calls ImGui interface functions
|
// 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
|
// which are statically bound to the obsolete module. To keep ImGui code functional we can redirect context handle
|
||||||
// to point to the new module.
|
// to point to the new module.
|
||||||
|
|
||||||
|
// When shutting down during hot-reloading, we might want to rewire handles used in statically bound functions
|
||||||
|
// or move data to a new module.
|
||||||
|
|
||||||
FModuleManager::Get().OnModulesChanged().AddLambda([this] (FName Name, EModuleChangeReason Reason)
|
FModuleManager::Get().OnModulesChanged().AddLambda([this] (FName Name, EModuleChangeReason Reason)
|
||||||
{
|
{
|
||||||
if (Reason == EModuleChangeReason::ModuleLoaded && Name == "ImGui")
|
if (Reason == EModuleChangeReason::ModuleLoaded && Name == "ImGui")
|
||||||
@ -161,8 +197,11 @@ void FImGuiModule::ShutdownModule()
|
|||||||
FImGuiModule& LoadedModule = FImGuiModule::Get();
|
FImGuiModule& LoadedModule = FImGuiModule::Get();
|
||||||
if (&LoadedModule != this)
|
if (&LoadedModule != this)
|
||||||
{
|
{
|
||||||
|
// Statically bound functions will be still made to the obsolete module so we need to
|
||||||
ImGuiImplementation::SetImGuiContextHandle(LoadedModule.GetImGuiContextHandle());
|
ImGuiImplementation::SetImGuiContextHandle(LoadedModule.GetImGuiContextHandle());
|
||||||
|
|
||||||
|
FImGuiDelegatesContainer::MoveContainer(LoadedModule.GetDelegatesContainer());
|
||||||
|
|
||||||
if (bMoveProperties)
|
if (bMoveProperties)
|
||||||
{
|
{
|
||||||
bMoveProperties = false;
|
bMoveProperties = false;
|
||||||
@ -184,6 +223,11 @@ ImGuiContext** FImGuiModule::GetImGuiContextHandle()
|
|||||||
{
|
{
|
||||||
return ImGuiImplementation::GetImGuiContextHandle();
|
return ImGuiImplementation::GetImGuiContextHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FImGuiDelegatesContainer& FImGuiModule::GetDelegatesContainer()
|
||||||
|
{
|
||||||
|
return FImGuiDelegatesContainer::Get();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FImGuiModuleProperties& FImGuiModule::GetProperties()
|
FImGuiModuleProperties& FImGuiModule::GetProperties()
|
||||||
|
@ -56,6 +56,11 @@ namespace Utilities
|
|||||||
return (World.WorldType == EWorldType::Editor) ? EDITOR_CONTEXT_INDEX : GetWorldContextIndex(World.GetGameInstance());
|
return (World.WorldType == EWorldType::Editor) ? EDITOR_CONTEXT_INDEX : GetWorldContextIndex(World.GetGameInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCEINLINE int32 GetWorldContextIndex(const UWorld* World)
|
||||||
|
{
|
||||||
|
return World ? GetWorldContextIndex(*World) : INVALID_CONTEXT_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -5,6 +5,43 @@
|
|||||||
#include <Core.h>
|
#include <Core.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to ImGui debug events called. World delegates are called once per frame to draw debug for owning world
|
||||||
|
* and are automatically cleared when that world becomes invalid. Multi-context delegates are called once for every
|
||||||
|
* world that needs to be debugged.
|
||||||
|
* In engine version 4.18 or later delegates are called during OnWorldPostActorTick event while in older versions
|
||||||
|
* 4.18 during OnWorldTickStart event. Calling behaviours can be changed in build configuration.
|
||||||
|
*/
|
||||||
|
class IMGUI_API FImGuiDelegates
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a delegate to ImGui world debug event for current world (GWorld).
|
||||||
|
* @returns Simple multicast delegate to debug events called once per frame to debug current world
|
||||||
|
*/
|
||||||
|
static FSimpleMulticastDelegate& OnWorldDebug();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a delegate to ImGui world debug event for given world.
|
||||||
|
* @param World - World for which we need a delegate
|
||||||
|
* @returns Simple multicast delegate to debug events called once per frame to debug given world
|
||||||
|
*/
|
||||||
|
static FSimpleMulticastDelegate& OnWorldDebug(UWorld* World);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a delegate to ImGui multi-context debug event.
|
||||||
|
* @returns Simple multicast delegate to debug events called once per frame for every world to debug
|
||||||
|
*/
|
||||||
|
static FSimpleMulticastDelegate& OnMultiContextDebug();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Enable to support legacy ImGui delegates API. */
|
||||||
|
#define IMGUI_WITH_OBSOLETE_DELEGATES 1
|
||||||
|
|
||||||
|
#if IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
|
||||||
/** Delegate that allows to subscribe for ImGui events. */
|
/** Delegate that allows to subscribe for ImGui events. */
|
||||||
typedef FSimpleMulticastDelegate::FDelegate FImGuiDelegate;
|
typedef FSimpleMulticastDelegate::FDelegate FImGuiDelegate;
|
||||||
|
|
||||||
@ -53,3 +90,5 @@ private:
|
|||||||
|
|
||||||
friend class FImGuiModule;
|
friend class FImGuiModule;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
@ -34,6 +34,8 @@ public:
|
|||||||
return FModuleManager::Get().IsModuleLoaded("ImGui");
|
return FModuleManager::Get().IsModuleLoaded("ImGui");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
/**
|
/**
|
||||||
* Add a delegate called at the end of editor debug frame to draw debug controls in its ImGui context, creating
|
* Add a delegate called at the end of editor debug frame to draw debug controls in its ImGui context, creating
|
||||||
@ -71,6 +73,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle);
|
virtual void RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle);
|
||||||
|
|
||||||
|
#endif // #if IMGUI_WITH_OBSOLETE_DELEGATES
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If it exists, get a handle to the texture with given resource name.
|
* If it exists, get a handle to the texture with given resource name.
|
||||||
*
|
*
|
||||||
@ -165,5 +169,6 @@ public:
|
|||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
virtual void SetProperties(const FImGuiModuleProperties& Properties);
|
virtual void SetProperties(const FImGuiModuleProperties& Properties);
|
||||||
virtual struct ImGuiContext** GetImGuiContextHandle();
|
virtual struct ImGuiContext** GetImGuiContextHandle();
|
||||||
|
virtual struct FImGuiDelegatesContainer& GetDelegatesContainer();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user