Got rid of multithreading in GameMode

This commit is contained in:
2026-02-27 17:49:29 -05:00
parent 7bb4854844
commit 8825fe3a1e
2 changed files with 48 additions and 70 deletions

View File

@@ -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);
}

View File

@@ -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<FlxSockets> 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.