Code to click a function in the blueprint editor and pop up the C++
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
diff -u --recursive UnrealEngine-5.3.1-release/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py UnrealEngine/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py
|
||||
--- UnrealEngine-5.3.1-release/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py 2023-09-27 09:48:07.000000000 -0400
|
||||
+++ UnrealEngine/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py 2025-06-19 17:47:01.619969745 -0400
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py /home/jyelon/integration.UE/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py 2025-09-08 15:15:35.242987722 -0400
|
||||
@@ -32,7 +32,7 @@
|
||||
if DataVal == 0:
|
||||
Val = 'NULL'
|
||||
@@ -22,11 +22,46 @@ diff -u --recursive UnrealEngine-5.3.1-release/Engine/Extras/LLDBDataFormatters/
|
||||
return Val
|
||||
|
||||
def UESignedCharSummaryProvider(valobj,dict):
|
||||
diff -u --recursive UnrealEngine-5.3.1-release/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp UnrealEngine/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp
|
||||
--- UnrealEngine-5.3.1-release/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp 2023-09-27 09:48:07.000000000 -0400
|
||||
+++ UnrealEngine/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp 2025-06-19 17:47:01.621969761 -0400
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp /home/jyelon/integration.UE/Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp 2026-03-02 15:28:34.593675093 -0500
|
||||
@@ -149,7 +149,7 @@
|
||||
FString SolutionDir = GetSolutionPath();
|
||||
TArray<FString> Args;
|
||||
Args.Add(MakePath(SolutionDir));
|
||||
- Args.Add(TEXT("-g ") + MakePath(FullPath) + FString::Printf(TEXT(":%d:%d"), LineNumber, ColumnNumber));
|
||||
+ Args.Add(TEXT("-g ") + MakePath(FullPath + FString::Printf(TEXT(":%d:%d"), LineNumber, ColumnNumber)));
|
||||
return Launch(Args);
|
||||
}
|
||||
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp /home/jyelon/integration.UE/Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp 2026-03-02 15:37:59.934459864 -0500
|
||||
@@ -463,7 +463,7 @@
|
||||
ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess");
|
||||
ISourceCodeAccessor& SourceCodeAccessor = SourceCodeAccessModule.GetAccessor();
|
||||
|
||||
-#if PLATFORM_WINDOWS
|
||||
+#if PLATFORM_WINDOWS || PLATFORM_LINUX
|
||||
FString SourceFileName;
|
||||
uint32 SourceLineNumber = 1;
|
||||
uint32 SourceColumnNumber = 0;
|
||||
@@ -622,8 +622,8 @@
|
||||
}
|
||||
|
||||
UE_LOG(LogSelectionDetails, Warning, TEXT("NavigateToFunctionSource: Unable to look up symbol: %s in module:%s"), *FunctionSymbolName, *FunctionModuleName);
|
||||
-
|
||||
-#endif // PLATFORM_WINDOWS
|
||||
+
|
||||
+#endif // PLATFORM_WINDOWS || PLATFORM_LINUX
|
||||
}
|
||||
|
||||
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp /home/jyelon/integration.UE/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp 2025-09-08 15:15:35.242987722 -0400
|
||||
@@ -299,6 +299,9 @@
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_SHOW_CURSOR, "1"); // When relative mouse mode is acive, don't hide cursor.
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // When relative mouse mode is active, don't hide cursor.
|
||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "0"); // Don't warp the cursor to the center in relative mouse mode.
|
||||
|
||||
+ // Unreal does its own dynamic capturing, we don't need SDL to do it.
|
||||
@@ -35,3 +70,96 @@ diff -u --recursive UnrealEngine-5.3.1-release/Engine/Source/Runtime/Application
|
||||
// If we're rendering offscreen, use the "dummy" SDL video driver
|
||||
if (FParse::Param(FCommandLine::Get(), TEXT("RenderOffScreen")) && !getenv("SDL_VIDEODRIVER"))
|
||||
{
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp /home/jyelon/integration.UE/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp 2026-03-02 15:37:24.464156072 -0500
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "HAL/ExceptionHandling.h"
|
||||
#include "HAL/PlatformProcess.h"
|
||||
#include "HAL/PlatformTime.h"
|
||||
+#include "Modules/ModuleManager.h"
|
||||
#include "AutoRTFM/AutoRTFM.h"
|
||||
|
||||
#include <link.h>
|
||||
@@ -1060,3 +1061,69 @@
|
||||
}
|
||||
ReportLock.Unlock();
|
||||
}
|
||||
+
|
||||
+bool FUnixPlatformStackWalk::GetFunctionDefinitionLocation(const FString& FunctionSymbolName, const FString& FunctionModuleName, FString& OutPathname, uint32& OutLineNumber, uint32& OutColumnNumber)
|
||||
+{
|
||||
+ // Find the .so path for this module.
|
||||
+ FString ModulePath;
|
||||
+ TArray<FModuleStatus> AllModules;
|
||||
+ FModuleManager::Get().QueryModules(AllModules);
|
||||
+ for (const FModuleStatus& Status : AllModules)
|
||||
+ {
|
||||
+ if (FPaths::GetBaseFilename(Status.FilePath) == FunctionModuleName)
|
||||
+ {
|
||||
+ ModulePath = Status.FilePath;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (ModulePath.IsEmpty())
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Debug symbols are in a separate .debug file alongside the .so.
|
||||
+ FString DebugPath = FPaths::ChangeExtension(ModulePath, TEXT("debug"));
|
||||
+ if (!FPaths::FileExists(DebugPath))
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Use lldb to look up the source file and line number.
|
||||
+ // Run: lldb -b -o "image lookup -v -n ClassName::FuncName" <debug_file>
|
||||
+ FString LldbParams = FString::Printf(TEXT("-b -o \"image lookup -v -n %s\" \"%s\""), *FunctionSymbolName, *DebugPath);
|
||||
+ int32 ReturnCode = 0;
|
||||
+ FString AllOutput;
|
||||
+ FString Errors;
|
||||
+ FPlatformProcess::ExecProcess(TEXT("/usr/bin/lldb"), *LldbParams, &ReturnCode, &AllOutput, &Errors);
|
||||
+ if (ReturnCode != 0)
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Parse the LineEntry from lldb verbose output.
|
||||
+ // Format: "LineEntry: [0x...-0x...): /path/to/file.cpp:132"
|
||||
+ TArray<FString> Lines;
|
||||
+ AllOutput.ParseIntoArrayLines(Lines);
|
||||
+ for (const FString& Line : Lines)
|
||||
+ {
|
||||
+ FString Trimmed = Line.TrimStartAndEnd();
|
||||
+ if (!Trimmed.StartsWith(TEXT("LineEntry:")))
|
||||
+ continue;
|
||||
+
|
||||
+ int32 ParenIndex = Trimmed.Find(TEXT("): "));
|
||||
+ if (ParenIndex == INDEX_NONE)
|
||||
+ continue;
|
||||
+ FString FileAndLine = Trimmed.Mid(ParenIndex + 3);
|
||||
+
|
||||
+ int32 ColonIndex;
|
||||
+ if (!FileAndLine.FindLastChar(TCHAR(':'), ColonIndex))
|
||||
+ continue;
|
||||
+
|
||||
+ OutPathname = FileAndLine.Left(ColonIndex);
|
||||
+ OutLineNumber = FCString::Atoi(*FileAndLine.Mid(ColonIndex + 1));
|
||||
+ OutColumnNumber = 0;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
diff -u --recursive '--exclude=*.o' '--exclude=*.d' '--exclude=Intermediate' '--exclude=Binaries' '--exclude=Saved' '--exclude=DerivedDataCache' '--exclude=*.pyc' '--exclude=__pycache__' /home/jyelon/integration.UE.orig/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h /home/jyelon/integration.UE/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h
|
||||
--- /home/jyelon/integration.UE.orig/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h 2025-03-11 10:33:14.000000000 -0400
|
||||
+++ /home/jyelon/integration.UE/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h 2026-03-02 15:36:22.690627000 -0500
|
||||
@@ -24,6 +24,8 @@
|
||||
static CORE_API void ThreadStackWalkAndDump(ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 ThreadId);
|
||||
static CORE_API int32 GetProcessModuleCount();
|
||||
static CORE_API int32 GetProcessModuleSignatures(FStackWalkModuleInfo *ModuleSignatures, const int32 ModuleSignaturesSize);
|
||||
+
|
||||
+ static CORE_API bool GetFunctionDefinitionLocation(const FString& FunctionSymbolName, const FString& FunctionModuleName, FString& OutPathname, uint32& OutLineNumber, uint32& OutColumnNumber);
|
||||
};
|
||||
|
||||
typedef FUnixPlatformStackWalk FPlatformStackWalk;
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#include "TriggeredTask.h"
|
||||
|
||||
FTriggeredTask::FTriggeredTask() {
|
||||
Client = nullptr;
|
||||
Thread = nullptr;
|
||||
ThreadStopRequested = false;
|
||||
CallEvent = nullptr;
|
||||
ReturnEvent = nullptr;
|
||||
}
|
||||
|
||||
uint32 FTriggeredTask::Run() {
|
||||
while (true)
|
||||
{
|
||||
CallEvent->Wait();
|
||||
if (ThreadStopRequested) {
|
||||
break;
|
||||
}
|
||||
// The payload.
|
||||
Client->Run();
|
||||
ReturnEvent->Trigger();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FTriggeredTask::Startup(FRunnable *client) {
|
||||
FScopeLock lock(&Mutex);
|
||||
if (Thread == nullptr) {
|
||||
Client = client;
|
||||
CallEvent = FPlatformProcess::GetSynchEventFromPool(false);
|
||||
ReturnEvent = FPlatformProcess::GetSynchEventFromPool(true);
|
||||
ReturnEvent->Trigger();
|
||||
Thread = FRunnableThread::Create(this, TEXT("Worker Thread"));
|
||||
}
|
||||
}
|
||||
|
||||
void FTriggeredTask::Shutdown() {
|
||||
FScopeLock lock(&Mutex);
|
||||
if (Thread != nullptr) {
|
||||
ReturnEvent->Wait();
|
||||
ThreadStopRequested = true;
|
||||
CallEvent->Trigger();
|
||||
delete Thread; // This waits for the thread to complete.
|
||||
Thread = nullptr;
|
||||
FPlatformProcess::ReturnSynchEventToPool(CallEvent);
|
||||
FPlatformProcess::ReturnSynchEventToPool(ReturnEvent);
|
||||
CallEvent = nullptr;
|
||||
ReturnEvent = nullptr;
|
||||
}
|
||||
ThreadStopRequested = false;
|
||||
}
|
||||
|
||||
void FTriggeredTask::Trigger() {
|
||||
FScopeLock lock(&Mutex);
|
||||
if (Thread != nullptr) {
|
||||
ReturnEvent->Reset();
|
||||
CallEvent->Trigger();
|
||||
}
|
||||
}
|
||||
|
||||
void FTriggeredTask::Wait() {
|
||||
FScopeLock lock(&Mutex);
|
||||
if (Thread != nullptr) {
|
||||
ReturnEvent->Wait();
|
||||
}
|
||||
}
|
||||
|
||||
bool FTriggeredTask::IsRunning() {
|
||||
FScopeLock lock(&Mutex);
|
||||
return (Thread != nullptr);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "HAL/Runnable.h"
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// TRIGGERED TASKS
|
||||
//
|
||||
// This is the situation where this class is
|
||||
// useful:
|
||||
//
|
||||
// * You have a function to run in the background.
|
||||
// * It should start the instant a foreground thread says "NOW".
|
||||
// * It should be run exactly once for each "NOW".
|
||||
// * The foreground thread eventually waits for the background thread to finish.
|
||||
//
|
||||
// To use this class, construct an FTriggeredTask,
|
||||
// and provide a runnable object. The runnable
|
||||
// object's "Run" method will get executed in
|
||||
// each time you call 'Trigger' on the FTriggeredTask.
|
||||
//
|
||||
///////////////////////////////////////////////
|
||||
|
||||
class FTriggeredTask : public FRunnable
|
||||
{
|
||||
private:
|
||||
// Mutex used by control routines.
|
||||
//
|
||||
FCriticalSection Mutex;
|
||||
|
||||
// The worker thread.
|
||||
//
|
||||
FRunnableThread* Thread;
|
||||
|
||||
// Used to tell the worker thread to stop.
|
||||
//
|
||||
bool ThreadStopRequested;
|
||||
|
||||
// This event is used to wake up the thread.
|
||||
//
|
||||
// This is an auto-reset event, meaning that each time we
|
||||
// call trigger, the background thread is gated exactly once.
|
||||
//
|
||||
// Normally, this means we want the worker to run the task
|
||||
// once. But if ThreadStopRequested is true, it means we
|
||||
// want the thread to exit.
|
||||
//
|
||||
FEvent* CallEvent;
|
||||
|
||||
// This event is used when the thread is done with its work.
|
||||
//
|
||||
// This is not an auto-reset event. This event stays triggered
|
||||
// whenever the background thread is not running.
|
||||
//
|
||||
FEvent* ReturnEvent;
|
||||
|
||||
// The client whose task we're triggering.
|
||||
//
|
||||
FRunnable* Client;
|
||||
|
||||
private:
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// This section contains routines that are
|
||||
// executed by the thread itself.
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// Method of FRunnable, called by the Luprex thread.
|
||||
//
|
||||
virtual uint32 Run() override;
|
||||
|
||||
public:
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// This section contains thread control routines.
|
||||
// These are not invoked by the thread, but by the
|
||||
// outside entity that started the thread.
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// Constructor.
|
||||
//
|
||||
// The client must outlive the FTriggeredTask.
|
||||
//
|
||||
FTriggeredTask();
|
||||
|
||||
// Startup.
|
||||
//
|
||||
// Bring the system online, put it in ready mode.
|
||||
//
|
||||
void Startup(FRunnable* client);
|
||||
|
||||
// Shutdown.
|
||||
//
|
||||
// Bring the system down, deallocate all threads.
|
||||
//
|
||||
void Shutdown();
|
||||
|
||||
// Trigger
|
||||
//
|
||||
// Run the client's 'RUN' method once, in the
|
||||
// background.
|
||||
//
|
||||
void Trigger();
|
||||
|
||||
// Wait
|
||||
//
|
||||
// Wait for the background task to finish its work.
|
||||
// If the background thread isn't running, then this
|
||||
// returns immediately.
|
||||
//
|
||||
void Wait();
|
||||
|
||||
// IsRunning
|
||||
//
|
||||
bool IsRunning();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user