From 8825fe3a1e49480ce2dac80acdbf8ae377d787ca Mon Sep 17 00:00:00 2001 From: jyelon Date: Fri, 27 Feb 2026 17:49:29 -0500 Subject: [PATCH] Got rid of multithreading in GameMode --- Source/Integration/LuprexGameModeBase.cpp | 91 +++++++++-------------- Source/Integration/LuprexGameModeBase.h | 27 ++++--- 2 files changed, 48 insertions(+), 70 deletions(-) diff --git a/Source/Integration/LuprexGameModeBase.cpp b/Source/Integration/LuprexGameModeBase.cpp index e00026e0..d606bc45 100644 --- a/Source/Integration/LuprexGameModeBase.cpp +++ b/Source/Integration/LuprexGameModeBase.cpp @@ -19,57 +19,19 @@ using namespace LpxCommonTypes; -ALuprexGameModeBase::ALuprexGameModeBase() -{ -} +ALuprexGameModeBase::ALuprexGameModeBase() {} +ALuprexGameModeBase::~ALuprexGameModeBase() {} -ALuprexGameModeBase::~ALuprexGameModeBase() -{ -} - -// This method runs in the background thread, -// at the moment we trigger it. -// -uint32 ALuprexGameModeBase::Run() { - FlxLockedWrapper lockedwrap; - if (lockedwrap->get_rescan_lua_source(lockedwrap.Get())) - { - drvutil::ostringstream srcpak; - FString LuprexRoot = FPaths::Combine(FPaths::ProjectDir(), TEXT("luprex")); - std::string srcpakerr = drvutil::package_lua_source(TCHAR_TO_UTF8(*LuprexRoot), &srcpak); - if (!srcpakerr.empty()) - { - FString FMessage((const UTF8CHAR *)(srcpakerr.c_str())); - UE_LOG(LogLuprexIntegration, Error, TEXT("Trying to read Lua source: %s"), *FMessage); - } - else - { - std::string_view srcpakv = srcpak.view(); - lockedwrap->play_access(lockedwrap.Get(), AccessKind::INVOKE_LUA_SOURCE, 0, srcpakv.size(), srcpakv.data(), nullptr, nullptr); - } - } - Sockets->Update(lockedwrap); - lockedwrap->play_update(lockedwrap.Get(), EngineSeconds); - Sockets->Update(lockedwrap); - return 0; -} void ALuprexGameModeBase::ResetToInitialState() { Playing = false; TickEnabled = true; - // Stop the tick functions. - FWorldDelegates::OnWorldPreActorTick.Remove(OnWorldPreActorTickHandle); + // Stop the tick function. FWorldDelegates::OnWorldPostActorTick.Remove(OnWorldPostActorTickHandle); - OnWorldPreActorTickHandle.Reset(); OnWorldPostActorTickHandle.Reset(); - // Shut down the thread - LuprexUpdateTask.Shutdown(); - - // Now that the thread's gone, we should be able to - // just claim and hold the lock on the wrapper. FlxLockedWrapper w; // Release and close all sockets. @@ -172,25 +134,45 @@ void ALuprexGameModeBase::UpdatePossessedTangible() { } } - -void ALuprexGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds) -{ - if(Playing && TickEnabled && (GetWorld() == InWorld) && (InLevelTick == LEVELTICK_All)) +void ALuprexGameModeBase::UpdateLuaSourceCode() { + FlxLockedWrapper lockedwrap; + if (lockedwrap->get_rescan_lua_source(lockedwrap.Get())) { - LuprexUpdateTask.Wait(); - EngineSeconds += deltaseconds; - UpdateConsoleOutput(); - UpdateTangibles(); - UpdatePossessedTangible(); - UpdateLookAt(); + drvutil::ostringstream srcpak; + FString LuprexRoot = FPaths::Combine(FPaths::ProjectDir(), TEXT("luprex")); + std::string srcpakerr = drvutil::package_lua_source(TCHAR_TO_UTF8(*LuprexRoot), &srcpak); + if (!srcpakerr.empty()) + { + FString FMessage((const UTF8CHAR *)(srcpakerr.c_str())); + UE_LOG(LogLuprexIntegration, Error, TEXT("Trying to read Lua source: %s"), *FMessage); + } + else + { + std::string_view srcpakv = srcpak.view(); + lockedwrap->play_access(lockedwrap.Get(), AccessKind::INVOKE_LUA_SOURCE, 0, srcpakv.size(), srcpakv.data(), nullptr, nullptr); + } } } +void ALuprexGameModeBase::UpdateSocketsAndLua() +{ + FlxLockedWrapper lockedwrap; + Sockets->Update(lockedwrap); + lockedwrap->play_update(lockedwrap.Get(), EngineSeconds); + Sockets->Update(lockedwrap); +} + void ALuprexGameModeBase::OnWorldPostActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds) { if(Playing && TickEnabled && (GetWorld() == InWorld) && (InLevelTick == LEVELTICK_All)) { - LuprexUpdateTask.Trigger(); + EngineSeconds += deltaseconds; + UpdateLuaSourceCode(); + UpdateSocketsAndLua(); + UpdateConsoleOutput(); + UpdateTangibles(); + UpdatePossessedTangible(); + UpdateLookAt(); } } @@ -206,7 +188,6 @@ void ALuprexGameModeBase::InitializeGlobalState() FlxLockedWrapper w; // Sanity checks. Make sure everything is clean. - checkf(!LuprexUpdateTask.IsRunning(), TEXT("There should be no thread here.")); checkf(w->engine == nullptr, TEXT("There should be no engine here.")); // If we failed to initialize the wrapper, print an error message. @@ -243,16 +224,14 @@ void ALuprexGameModeBase::InitializeGlobalState() } } - // If we successfully created a luprex engine, create a socket system and a worker thread. + // If we successfully created a luprex engine, create a socket system. if (Playing) { Sockets.Reset(FlxSockets::Create(w)); std::string error = Sockets->GetError(); check(error.empty()); - LuprexUpdateTask.Startup(this); } if (Playing) { - OnWorldPreActorTickHandle = FWorldDelegates::OnWorldPreActorTick.AddUObject(this, &ALuprexGameModeBase::OnWorldPreActorTick); OnWorldPostActorTickHandle = FWorldDelegates::OnWorldPostActorTick.AddUObject(this, &ALuprexGameModeBase::OnWorldPostActorTick); } diff --git a/Source/Integration/LuprexGameModeBase.h b/Source/Integration/LuprexGameModeBase.h index 65775848..cefeb808 100644 --- a/Source/Integration/LuprexGameModeBase.h +++ b/Source/Integration/LuprexGameModeBase.h @@ -6,7 +6,6 @@ #include "Engine/HitResult.h" #include "GameFramework/GameModeBase.h" #include "LuprexSockets.h" -#include "TriggeredTask.h" #include "BreakToDebugger.h" #include "LuprexGameModeBase.generated.h" @@ -14,7 +13,7 @@ * */ UCLASS(BlueprintType) -class INTEGRATION_API ALuprexGameModeBase : public AGameModeBase, public FRunnable +class INTEGRATION_API ALuprexGameModeBase : public AGameModeBase { GENERATED_BODY() @@ -80,13 +79,17 @@ public: // It is up to the blueprint code to actually determine what we're looking at. void UpdateLookAt(); - // Pre-tick and post-tick functions. - void OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float InDeltaSeconds); - void OnWorldPostActorTick(UWorld* InWorld, ELevelTick InLevelTick, float InDeltaSeconds); + // If the engine wants a new copy of the lua source code, + // provide it. + void UpdateLuaSourceCode(); - // The run function is called by a background thread - // to update luprex sockets and update luprex itself. - virtual uint32 Run() override; + // Update Sockets and Lua. Feeds socket data into the luprex engine, + // and also calls play_update, the main Lua update function that causes + // Luprex to execute the majority of all the Lua code that needs processing. + void UpdateSocketsAndLua(); + + // Post-tick function. + void OnWorldPostActorTick(UWorld* InWorld, ELevelTick InLevelTick, float InDeltaSeconds); // Get the current Luprex Game Mode Base, given a Context object. static ALuprexGameModeBase *FromContext(const UObject *Context); @@ -101,10 +104,7 @@ public: UPROPERTY(EditAnywhere, Category="Debugging Tools") ElxBreakToDebuggerThreshold BreakToDebuggerLogVerbosity; - // This utility runs the luprex update and socket update in a thread. - FTriggeredTask LuprexUpdateTask; - - // Luprex socket system. Aside from construction, only touched by Luprex thread. + // Luprex socket system. TUniquePtr Sockets; // True if 'BeginPlay' has been successfully completed. @@ -122,8 +122,7 @@ public: // When do we next rotate the cube. float NextRotateCube = 1.0f; - // These allow us to pre-tick and post-tick. - FDelegateHandle OnWorldPreActorTickHandle; + // This allows us to post-tick. FDelegateHandle OnWorldPostActorTickHandle; // The device that implements BreakToDebuggerLogVerbosity, above.