Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NetImgui Update 1.6 #56

Open
wants to merge 28 commits into
base: net_imgui
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
79ba3a7
Added support for netImgui.
sammyfreg Sep 6, 2020
beb0ecc
netImgui: Fix compile and running error in game mode
sammyfreg Sep 6, 2020
6dcc1b0
NetImgui: Added mirroring option
sammyfreg Sep 9, 2020
a686699
Fix for Texture format detection and disconnect request
sammyfreg Sep 12, 2020
ed0d3b0
Added : Dual Draw support
sammyfreg Sep 12, 2020
65ef856
Added support of Unreal Sockets instead of using Windows code. Every …
sammyfreg Sep 13, 2020
db77175
Changed context index mapping to fix issues with multi-PIE debugging …
segross Sep 15, 2020
860b922
Status update with information about NetImgui.
segross Sep 18, 2020
f3adb81
Merge pull request #1 from segross/net_imgui
sammyfreg Sep 19, 2020
0481be6
Bugfix: making sure sockets are all closed before exiting netImgui sh…
sammyfreg Sep 19, 2020
ea74c3c
Fixed Linux crash caused by wrong mapping of key codes.
segross Sep 20, 2020
5f656cd
Merge pull request #2 from segross/master
sammyfreg Jan 23, 2021
855ebec
Merge pull request #3 from segross/net_imgui
sammyfreg Jan 23, 2021
72abebb
Update DearImgui 1.80, NetImgui 1.3
sammyfreg Feb 14, 2021
883416d
Missing ImGui context release
sammyfreg Feb 14, 2021
b0c6093
Prevent crash while cooking
sammyfreg Feb 16, 2021
1fe4982
Case sensitive include fix
sammyfreg Feb 16, 2021
47473c3
Fix deprecation warnings in IsBindable (#45)
Grimeh Mar 4, 2021
39c3ece
Updated copyright date.
segross Apr 15, 2021
9f41d09
Fixed potential for initialization fiasco when using delegates contai…
segross Apr 15, 2021
e00a133
Fixed cached resource handles getting invalid after reloading texture…
segross Apr 16, 2021
d04bc05
Merge branch 'master' of https://github.com/segross/UnrealImGui
sammyfreg Jul 14, 2021
c798b34
Added a define programmer can rely on to know if UnrealImgui is active
sammyfreg Jul 16, 2021
9979542
Update to NetImgui 1.5
sammyfreg Jul 17, 2021
5f56f1e
Merge remote-tracking branch 'Original/net_imgui' into Update_1_5
sammyfreg Jul 17, 2021
60a978f
Fix support of 32bits indices
sammyfreg Jul 18, 2021
9d08c7b
Update to NetImgui 1.6 (bug fixes) and Added UnrealCommands support (…
sammyfreg Aug 15, 2021
8feb5d3
Moved ImGuiUnrealCommand to 3rd party folder
sammyfreg Aug 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ 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.
- Fixed cached resource handles getting invalid after reloading texture resources.

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.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2017-2020 Sebastian Gross
Copyright (c) 2017-2021 Sebastian Gross

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Binary file modified NetImguiServer/Background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified NetImguiServer/netImguiServer.exe
Binary file not shown.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----
Expand Down
6 changes: 4 additions & 2 deletions Source/ImGui/ImGui.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public ImGui(TargetInfo Target)
// Developer modules are automatically loaded only in editor builds but can be stripped out from other builds.
// Enable runtime loader, if you want this module to be automatically loaded in runtime builds (monolithic).
bool bEnableRuntimeLoader = true;
bool bUnrealImguiEnabled = true;

PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

Expand Down Expand Up @@ -66,7 +67,8 @@ public ImGui(TargetInfo Target)
"InputCore",
"Slate",
"SlateCore",
"NetImguiLibrary"
"NetImguiLibrary",
"ImGuiUnrealCommandLibrary"
// ... add private dependencies that you statically link with here ...
}
);
Expand Down Expand Up @@ -96,7 +98,7 @@ public ImGui(TargetInfo Target)
#if !UE_4_19_OR_LATER
List<string> PrivateDefinitions = Definitions;
#endif

PublicDefinitions.Add(string.Format("UNREAL_IMGUI_ENABLED={0}", bUnrealImguiEnabled ? 1 : 0));
PrivateDefinitions.Add(string.Format("RUNTIME_LOADER_ENABLED={0}", bEnableRuntimeLoader ? 1 : 0));
}
}
19 changes: 11 additions & 8 deletions Source/ImGui/Private/ImGuiDelegatesContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -36,22 +35,26 @@ 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();
}

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)
Expand Down
35 changes: 22 additions & 13 deletions Source/ImGui/Private/ImGuiModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,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."));
Expand Down Expand Up @@ -152,10 +164,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)
{
Expand All @@ -173,16 +192,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()
Expand Down
32 changes: 30 additions & 2 deletions Source/ImGui/Private/ImGuiModuleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@

#include <Framework/Application/SlateApplication.h>
#include <Modules/ModuleManager.h>

#include <imgui.h>


// High enough z-order guarantees that ImGui output is rendered on top of the game UI.
constexpr int32 IMGUI_WIDGET_Z_ORDER = 10000;

// Module texture names.
const static FName PlainTextureName = "ImGuiModule_Plain";
const static FName FontAtlasTextureName = "ImGuiModule_FontAtlas";

#if IMGUI_UNREAL_COMMAND_ENABLED
#include "ImGuiUnrealCommand.h"
#include "ImGuiUnrealCommand.cpp" // Importing the source file for compilation
static UECommandImgui::CommandContext* spUECommandContext = nullptr;
#endif

FImGuiModuleManager::FImGuiModuleManager()
: Commands(Properties)
, Settings(Properties, Commands)
Expand All @@ -42,6 +46,14 @@ FImGuiModuleManager::FImGuiModuleManager()
// We need to add widgets to active game viewports as they won't generate on-created events. This is especially
// important during hot-reloading.
AddWidgetsToActiveViewports();

#if IMGUI_UNREAL_COMMAND_ENABLED
spUECommandContext = UECommandImgui::Create();
// Commented code demonstrating how to add/modify Presets
// Could also modify the list of 'Default Presets' directly (UECommandImgui::sDefaultPresets)
//UECommandImgui::AddPresetFilters(spUECommandContext, TEXT("ExamplePreset"), {"ai.Debug", "fx.Dump"});
//UECommandImgui::AddPresetCommands(spUECommandContext, TEXT("ExamplePreset"), {"Stat Unit", "Stat Fps"});
#endif
}

FImGuiModuleManager::~FImGuiModuleManager()
Expand Down Expand Up @@ -69,6 +81,9 @@ FImGuiModuleManager::~FImGuiModuleManager()
}
}

#if IMGUI_UNREAL_COMMAND_ENABLED
UECommandImgui::Destroy(spUECommandContext);
#endif
// Deactivate this manager.
ReleaseTickInitializer();
UnregisterTick();
Expand Down Expand Up @@ -231,4 +246,17 @@ void FImGuiModuleManager::OnContextProxyCreated(int32 ContextIndex, FImGuiContex
// Make sure that textures are loaded before the first Proxy Context is created.
LoadTextures();
ContextProxy.OnDraw().AddLambda([this, ContextIndex]() { ImGuiDemo.DrawControls(ContextIndex); });

#if IMGUI_UNREAL_COMMAND_ENABLED
ContextProxy.OnDraw().AddLambda([this, ContextIndex]() {
// Add Main Menu entry to toggle Unreal Command Window visibility
if (ImGui::BeginMainMenuBar()) {
ImGui::MenuItem("Unreal-Commands", nullptr, &UECommandImgui::IsVisible(spUECommandContext) );
ImGui::EndMainMenuBar();
}

// Always try displaying the 'Unreal Command Imgui' Window (handle Window visibily internally)
UECommandImgui::Show(spUECommandContext);
});
#endif
}
15 changes: 12 additions & 3 deletions Source/ImGui/Private/TextureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* I

// Create brush and resource handle for input texture.
Brush.SetResourceObject(InTexture);
ResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
}

FTextureManager::FTextureEntry::~FTextureEntry()
Expand All @@ -154,7 +154,7 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu
Name = MoveTemp(Other.Name);
Texture = MoveTemp(Other.Texture);
Brush = MoveTemp(Other.Brush);
ResourceHandle = MoveTemp(Other.ResourceHandle);
CachedResourceHandle = MoveTemp(Other.CachedResourceHandle);

// Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
// of ownership and mark it as empty/reusable.
Expand All @@ -163,6 +163,15 @@ FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextu
return *this;
}

const FSlateResourceHandle& FTextureManager::FTextureEntry::GetResourceHandle() const
{
if (!CachedResourceHandle.IsValid() && Brush.HasUObject())
{
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
}
return CachedResourceHandle;
}

void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
{
if (bReleaseResources)
Expand All @@ -187,5 +196,5 @@ void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
// Clean fields to make sure that we don't reference released or moved resources.
Texture.Reset();
Brush = FSlateNoResource();
ResourceHandle = FSlateResourceHandle();
CachedResourceHandle = FSlateResourceHandle();
}
19 changes: 11 additions & 8 deletions Source/ImGui/Private/TextureManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ class FTextureManager
// @returns The index of a texture with given name or INDEX_NONE if there is no such texture
TextureIndex FindTextureIndex(const FName& Name) const
{
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.Name == Name; });
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; });
}

// Get the name of a texture at given index. Returns NAME_None, if index is out of range.
// @param Index - Index of a texture
// @returns The name of a texture at given index or NAME_None if index is out of range.
FName GetTextureName(TextureIndex Index) const
{
return IsInRange(Index) ? TextureResources[Index].Name : NAME_None;
return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None;
}

// Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
Expand All @@ -59,7 +59,7 @@ class FTextureManager
// found at given index
const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
{
return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle;
return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle();
}

// Create a texture from raw data.
Expand Down Expand Up @@ -118,7 +118,7 @@ class FTextureManager
// Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
FORCEINLINE bool IsValidTexture(TextureIndex Index) const
{
return IsInRange(Index) && TextureResources[Index].Name != NAME_None;
return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None;
}

// Entry for texture resources. Only supports explicit construction.
Expand All @@ -137,14 +137,17 @@ class FTextureManager
// ... but we need move assignment to support reusing entries.
FTextureEntry& operator=(FTextureEntry&& Other);

FName Name = NAME_None;
TWeakObjectPtr<UTexture2D> Texture;
FSlateBrush Brush;
FSlateResourceHandle ResourceHandle;
const FName& GetName() const { return Name; }
const FSlateResourceHandle& GetResourceHandle() const;

private:

void Reset(bool bReleaseResources);

FName Name = NAME_None;
mutable FSlateResourceHandle CachedResourceHandle;
TWeakObjectPtr<UTexture2D> Texture;
FSlateBrush Brush;
};

TArray<FTextureEntry> TextureResources;
Expand Down
2 changes: 1 addition & 1 deletion Source/ImGui/Private/ThirdPartyBuildImGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct FImGuiContextHandle : public Utilities::TRedirectingHandle<ImGuiContext*>
{
if (FImGuiModule* Module = FModuleManager::GetModulePtr<FImGuiModule>("ImGui"))
{
SetParent(&Module->GetImGuiContextHandle());
SetParent(Module->ImGuiContextHandle);
}
}
};
Expand Down
5 changes: 5 additions & 0 deletions Source/ImGui/Private/Utilities/DebugExecBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ namespace

bool IsBindable(const FKey& Key)
{
#if ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API
return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsFloatAxis() && !Key.IsVectorAxis()
&& !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
#else
return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsAxis1D() && !Key.IsAxis2D()
&& !Key.IsAxis3D() && !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
#endif
}

void UpdatePlayerInput(UPlayerInput* PlayerInput, const FKeyBind& KeyBind)
Expand Down
6 changes: 3 additions & 3 deletions Source/ImGui/Private/Utilities/RedirectingHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions Source/ImGui/Private/VersionCompatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@
// Starting from version 4.24, world actor tick event has additional world parameter.
#define ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK BELOW_ENGINE_VERSION(4, 24)

// Starting from version 4.26, FKey::IsFloatAxis and FKey::IsVectorAxis are deprecated and replaced with FKey::IsAxis[1|2|3]D methods.
#define ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API BELOW_ENGINE_VERSION(4, 26)
Loading