Fixed potential for initialization fiasco when using delegates container. Fixed bug in code protecting redirecting handles from self-referencing. Updated project version and status.

This commit is contained in:
Sebastian 2021-04-14 23:11:49 -04:00
parent 39c3eced41
commit 9f41d0906e
8 changed files with 56 additions and 30 deletions

View File

@ -5,6 +5,10 @@ Versions marked as 'unofficial' are labelled only for the needs of this changelo
Change History
--------------
Version: 1.22 (2021/04)
- Fixed potential for initialization fiasco when using delegates container.
- Fixed bug in code protecting redirecting handles from self-referencing.
Version: 1.21 (2020/07-09)
Improving stability
- Fixed a crash in the input handler caused by invalidated by hot-reload instance trying to unregister a delegate.

View File

@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.21",
"VersionName": "1.22",
"FriendlyName": "ImGui",
"Description": "",
"Category": "Debug",

View File

@ -9,14 +9,24 @@ Dear ImGui is an immediate-mode graphical user interface library that is very li
Status
------
Version: 1.21
Version: 1.22
ImGui version: 1.74
Supported engine version: 4.25*
Supported engine version: 4.26*
\* *Plugin has been tested and if necessary updated to compile and work with this engine version. As long as possible I will try to maintain backward compatibility of existing features and possibly but not necessarily when adding new features. When it comes to bare-bone ImGui version it should be at least backward compatible with the engine version 4.15. For NetImgui it needs to be determined.*
Current work
------------
Currently, I'm a little busy outside of this project so changes come slowly. But here is what to expect in the reasonably near future:
- Stability first, so fixes for more critical issues like an invalidation of handles after reloading texture resources will be pushed first. The same goes for merges.
- There are a few smaller issues that I'm aware of and that might be not reported but which I want to fix.
- ImGui needs to be updated.
- Smaller features might be slowly pushed but bigger ones will need to wait. The same goes for merges.
- There is a branch with NetImgui which is really good, and which will be eventually merged to master, but first I want to fix a few issues that I know about (some are discussed in thread #28). In the meantime, the NetImgui branch is pretty much ready to use.
About
-----

View File

@ -11,11 +11,10 @@
// Non-editor version without container redirection
//
static FImGuiDelegatesContainer DelegatesContainer;
FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
{
return DelegatesContainer;
static FImGuiDelegatesContainer* Container = new FImGuiDelegatesContainer();
return *Container;
}
#endif // !WITH_EDITOR
@ -36,14 +35,11 @@ struct FImGuiDelegatesContainerHandle : Utilities::TRedirectingHandle<FImGuiDele
{
if (FImGuiModule* Module = FModuleManager::GetModulePtr<FImGuiModule>("ImGui"))
{
SetParent(&Module->GetDelegatesContainerHandle());
SetParent(Module->DelegatesContainerHandle);
}
}
};
static FImGuiDelegatesContainer DelegatesContainer;
static FImGuiDelegatesContainerHandle DelegatesHandle(DelegatesContainer);
FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
{
return GetHandle().Get();
@ -51,7 +47,14 @@ FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
FImGuiDelegatesContainerHandle& FImGuiDelegatesContainer::GetHandle()
{
return DelegatesHandle;
struct FContainerInstance
{
FContainerInstance() : Container(), Handle(Container) {}
FImGuiDelegatesContainer Container;
FImGuiDelegatesContainerHandle Handle;
};
static FContainerInstance* Instance = new FContainerInstance();
return Instance->Handle;
}
void FImGuiDelegatesContainer::MoveContainer(FImGuiDelegatesContainerHandle& OtherContainerHandle)

View File

@ -30,7 +30,7 @@ struct FImGuiContextHandle : public Utilities::TRedirectingHandle<ImGuiContext*>
{
if (FImGuiModule* Module = FModuleManager::GetModulePtr<FImGuiModule>("ImGui"))
{
SetParent(&Module->GetImGuiContextHandle());
SetParent(Module->ImGuiContextHandle);
}
}
};

View File

@ -100,6 +100,18 @@ void FImGuiModule::ReleaseTexture(const FImGuiTextureHandle& Handle)
void FImGuiModule::StartupModule()
{
// Initialize handles to allow cross-module redirections. Other handles will always look for parents in the active
// module, which means that we can only redirect to started modules. We don't have to worry about self-referencing
// as local handles are guaranteed to be constructed before initializing pointers.
// This supports in-editor recompilation and hot-reloading after compiling from the command line. The latter method
// theoretically doesn't support plug-ins and will not load re-compiled module, but its handles will still redirect
// to the active one.
#if WITH_EDITOR
ImGuiContextHandle = &ImGuiImplementation::GetContextHandle();
DelegatesContainerHandle = &FImGuiDelegatesContainer::GetHandle();
#endif
// Create managers that implements module logic.
checkf(!ImGuiModuleManager, TEXT("Instance of the ImGui Module Manager already exists. Instance should be created only during module startup."));
@ -148,10 +160,17 @@ void FImGuiModule::ShutdownModule()
FImGuiModule& LoadedModule = FImGuiModule::Get();
if (&LoadedModule != this)
{
// Statically bound functions will be still made to the obsolete module so we need to
ImGuiImplementation::SetParentContextHandle(LoadedModule.GetImGuiContextHandle());
// Statically bound functions can be bound to the obsolete module, so we need to manually redirect.
FImGuiDelegatesContainer::MoveContainer(LoadedModule.GetDelegatesContainerHandle());
if (LoadedModule.ImGuiContextHandle)
{
ImGuiImplementation::SetParentContextHandle(*LoadedModule.ImGuiContextHandle);
}
if (LoadedModule.DelegatesContainerHandle)
{
FImGuiDelegatesContainer::MoveContainer(*LoadedModule.DelegatesContainerHandle);
}
if (bMoveProperties)
{
@ -169,16 +188,6 @@ void FImGuiModule::SetProperties(const FImGuiModuleProperties& Properties)
{
ImGuiModuleManager->GetProperties() = Properties;
}
FImGuiContextHandle& FImGuiModule::GetImGuiContextHandle()
{
return ImGuiImplementation::GetContextHandle();
}
FImGuiDelegatesContainerHandle& FImGuiModule::GetDelegatesContainerHandle()
{
return FImGuiDelegatesContainer::GetHandle();
}
#endif
FImGuiModuleProperties& FImGuiModule::GetProperties()

View File

@ -8,8 +8,8 @@
namespace Utilities
{
// Handle initialized as a pointer to a default value, but once attached it will follow the parent handle.
// When detached it will revert back to the default value. Intended for cross-module redirections.
// Handle initialized as a pointer to a default value, but can be redirected to follow other handles.
// When detached, it will revert to the default value. Intended for cross-module redirections.
template<typename T>
struct TRedirectingHandle
{
@ -49,7 +49,7 @@ namespace Utilities
}
// Protecting from setting itself as a parent.
Parent = (Parent != this) ? InParent : nullptr;
Parent = (InParent != this) ? InParent : nullptr;
if (Parent)
{

View File

@ -168,8 +168,8 @@ private:
#if WITH_EDITOR
virtual void SetProperties(const FImGuiModuleProperties& Properties);
virtual struct FImGuiContextHandle& GetImGuiContextHandle();
virtual struct FImGuiDelegatesContainerHandle& GetDelegatesContainerHandle();
struct FImGuiContextHandle* ImGuiContextHandle = nullptr;
struct FImGuiDelegatesContainerHandle* DelegatesContainerHandle = nullptr;
friend struct FImGuiContextHandle;
friend struct FImGuiDelegatesContainerHandle;
#endif