From dbdb0410eb552816c7cf717efb1575978cfc7ff1 Mon Sep 17 00:00:00 2001 From: Jaemin Date: Fri, 14 Dec 2018 15:08:04 +0900 Subject: [PATCH] Support interactive console return value to output --- Source/PythonConsole/Private/SPythonLog.cpp | 9 ++-- .../Private/UnrealEnginePython.cpp | 50 +++++++++++++++---- .../Public/UnrealEnginePython.h | 4 +- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/Source/PythonConsole/Private/SPythonLog.cpp b/Source/PythonConsole/Private/SPythonLog.cpp index 555141be4..905b8fa9c 100644 --- a/Source/PythonConsole/Private/SPythonLog.cpp +++ b/Source/PythonConsole/Private/SPythonLog.cpp @@ -238,7 +238,8 @@ void SPythonConsoleInputBox::OnTextCommitted(const FText& InText, ETextCommit::T else { IsMultiline = false; - PythonModule.RunString(TCHAR_TO_UTF8(*MultilineString)); + FString ret_str = PythonModule.RunString(TCHAR_TO_UTF8(*MultilineString)); + UE_LOG(LogTemp, Log, TEXT("%s"), *ret_str); } } else if (ExecString.EndsWith(":")) @@ -248,7 +249,8 @@ void SPythonConsoleInputBox::OnTextCommitted(const FText& InText, ETextCommit::T } else { - PythonModule.RunString(TCHAR_TO_UTF8(*ExecString)); + FString ret_str = PythonModule.RunString(TCHAR_TO_UTF8(*ExecString)); + UE_LOG(LogTemp, Log, TEXT("%s"), *ret_str); } } @@ -256,7 +258,8 @@ void SPythonConsoleInputBox::OnTextCommitted(const FText& InText, ETextCommit::T { IsMultiline = false; FUnrealEnginePythonModule &PythonModule = FModuleManager::GetModuleChecked("UnrealEnginePython"); - PythonModule.RunString(TCHAR_TO_UTF8(*MultilineString)); + FString ret_str = PythonModule.RunString(TCHAR_TO_UTF8(*MultilineString)); + UE_LOG(LogTemp, Log, TEXT("%s"), *ret_str); } } diff --git a/Source/UnrealEnginePython/Private/UnrealEnginePython.cpp b/Source/UnrealEnginePython/Private/UnrealEnginePython.cpp index 211124849..aa90930e9 100644 --- a/Source/UnrealEnginePython/Private/UnrealEnginePython.cpp +++ b/Source/UnrealEnginePython/Private/UnrealEnginePython.cpp @@ -547,22 +547,35 @@ void FUnrealEnginePythonModule::ShutdownModule() } } -void FUnrealEnginePythonModule::RunString(char *str) +FString FUnrealEnginePythonModule::RunString(char *str) { FScopePythonGIL gil; - PyObject *eval_ret = PyRun_String(str, Py_file_input, (PyObject *)main_dict, (PyObject *)local_dict); + PyObject *eval_ret = PyRun_String(str, Py_single_input, (PyObject *)main_dict, (PyObject *)local_dict); if (!eval_ret) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) { PyErr_Clear(); - return; + return ""; } unreal_engine_py_log_error(); - return; + return ""; } + + FString ue4_str_ret; + if (eval_ret != Py_None) + { + PyObject *stringified = PyObject_Str(eval_ret); + if (!stringified) + return "argument cannot be casted to string"; + + ue4_str_ret = UTF8_TO_TCHAR(UEPyUnicode_AsUTF8(stringified)); + } + Py_DECREF(eval_ret); + + return ue4_str_ret; } #if PLATFORM_MAC @@ -626,7 +639,7 @@ FString FUnrealEnginePythonModule::Pep8ize(FString Code) } -void FUnrealEnginePythonModule::RunFile(char *filename) +FString FUnrealEnginePythonModule::RunFile(char *filename) { FScopePythonGIL gil; FString full_path = UTF8_TO_TCHAR(filename); @@ -652,7 +665,7 @@ void FUnrealEnginePythonModule::RunFile(char *filename) if (!foundFile) { UE_LOG(LogPython, Error, TEXT("Unable to find file %s"), UTF8_TO_TCHAR(filename)); - return; + return ""; } #if PY_MAJOR_VERSION >= 3 @@ -662,14 +675,14 @@ void FUnrealEnginePythonModule::RunFile(char *filename) if (fopen_s(&fd, TCHAR_TO_UTF8(*full_path), "r") != 0) { UE_LOG(LogPython, Error, TEXT("Unable to open file %s"), *full_path); - return; + return ""; } #else fd = fopen(TCHAR_TO_UTF8(*full_path), "r"); if (!fd) { UE_LOG(LogPython, Error, TEXT("Unable to open file %s"), *full_path); - return; + return ""; } #endif @@ -680,12 +693,20 @@ void FUnrealEnginePythonModule::RunFile(char *filename) if (PyErr_ExceptionMatches(PyExc_SystemExit)) { PyErr_Clear(); - return; + return ""; } unreal_engine_py_log_error(); - return; + return ""; } + + PyObject *stringified = PyObject_Str(eval_ret); + if (!stringified) + return "argument cannot be casted to string"; + + FString ue4_string = UTF8_TO_TCHAR(UEPyUnicode_AsUTF8(stringified)); Py_DECREF(eval_ret); + + return ue4_string; #else // damn, this is horrible, but it is the only way i found to avoid the CRT error :( FString command = FString::Printf(TEXT("execfile(\"%s\")"), *full_path); @@ -698,8 +719,15 @@ void FUnrealEnginePythonModule::RunFile(char *filename) return; } unreal_engine_py_log_error(); - return; + return ""; } + + PyObject *stringified = PyObject_Str(eval_ret); + if (!stringified) + return "argument cannot be casted to string"; + + FString ue4_string = UTF8_TO_TCHAR(UEPyUnicode_AsUTF8(stringified)); + return ue4_string; #endif } diff --git a/Source/UnrealEnginePython/Public/UnrealEnginePython.h b/Source/UnrealEnginePython/Public/UnrealEnginePython.h index 1806609f0..822313209 100644 --- a/Source/UnrealEnginePython/Public/UnrealEnginePython.h +++ b/Source/UnrealEnginePython/Public/UnrealEnginePython.h @@ -104,8 +104,8 @@ class UNREALENGINEPYTHON_API FUnrealEnginePythonModule : public IModuleInterface virtual void StartupModule() override; virtual void ShutdownModule() override; - void RunString(char *); - void RunFile(char *); + FString RunString(char *); + FString RunFile(char *); #if PLATFORM_MAC void RunStringInMainThread(char *);