Files
integration/Source/Integration/LuprexGameModeBase.h
2026-02-09 13:54:00 -05:00

200 lines
6.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "lpx-enginewrapper.hpp"
#include "StringDecoder.h"
#include "TangibleManager.h"
#include "AssetLookup.h"
#include "LuprexSockets.h"
#include "TriggeredTask.h"
#include "BlueprintErrors.h"
#include "Blueprint/UserWidget.h"
#include "Widgets/CommonActivatableWidgetContainer.h"
#include "CommonActivatableWidget.h"
#include "LuprexGameModeBase.generated.h"
class UlxLuaValues;
UCLASS(BlueprintType)
class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Luprex|Miscellaneous")
void ReadLuaConfiguration(UlxLuaValues *Config);
};
/**
*
*/
UCLASS(BlueprintType)
class INTEGRATION_API ALuprexGameModeBase : public AGameModeBase, public FRunnable
{
GENERATED_BODY()
public:
ALuprexGameModeBase();
~ALuprexGameModeBase();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason);
// Delete all the state created in BeginPlay. That
// includes: the Luprex engine, the thread, and the socket state.
void ResetToInitialState();
// Initialize the Luprex DLL, and do other global initialization.
void InitializeGlobalState();
// Send prints into Unreal, for display on the virtual console.
UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Miscellaneous")
void ConsoleAddOutput(const FString& text);
UFUNCTION(BlueprintCallable, Category = "Luprex|Miscellaneous")
int64 GetPlayerId();
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context"), Category = "Luprex|Look-At Detection")
static void SetLookAt(const UObject *Context, const FHitResult &HitResult);
UFUNCTION(BlueprintPure, meta = (WorldContext = "Context"),Category = "Luprex|Look-At Detection")
static const FHitResult &GetLookAt(const UObject *Context) { return FromContext(Context)->CurrentLookAt; }
UFUNCTION(BlueprintPure, meta = (WorldContext = "Context"),Category = "Luprex|Look-At Detection")
static const AActor *GetLookAtActor(const UObject *Context) { return FromContext(Context)->CurrentLookAt.GetActor(); }
UFUNCTION(BlueprintPure, meta = (WorldContext = "Context"),Category = "Luprex|Look-At Detection")
static FVector2D GetLookAtPixel(const UObject *Context);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context"), Category = "Luprex|Look-At Detection")
static void SetLookAtChanged(const UObject* Context);
//
// Look-At Related Events
//
UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Look-At Detection")
void CalculateLookAt(APlayerController *PlayerController);
UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Look-At Detection")
void LookAtChanged();
// Assemble a lua call. Note that this is the lowest-level interface.
// These functions are wrapped by the functions in UlxLuaCallLibrary,
// and those in turn are wrapped by the K2Node "LuaInvoke" and "LuaProbe".
//
// At this level, the process of calling Lua is:
//
// * Use LuaCallBegin
// * Get the lua call buffer:
// - add a class name
// - add a function name
// - add function parameters
// * Use LuaCallEnd.
// * Process any return values in the UlxLuaValues array.
//
FlxStreamBuffer &LuaCallBegin() { LuaCallBuffer.clear(); return LuaCallBuffer; }
FlxStreamBuffer &LuaCallGetBuffer() { return LuaCallBuffer; }
UlxLuaValues *LuaCallEnd(AccessKind kind);
UlxLuaValues *LuaCallEnd(AccessKind kind, int64 place_id);
UlxLuaValues *LuaCallEnd(AccessKind kind, AActor *place);
void LuaCallClear() { LuaCallBuffer.clear(); }
// Validate some lua code. Returns an error message.
// If the lua is well-formed, the error message is the
// empty string. The syntax of the code is checked using
// an otherwise empty lua interpreter, so this is purely
// a syntax check.
//
FString ValidateLuaExpr(const FString &Code);
// Invoke some lua code.
//
void InvokeLuaExpr(const FString &Code);
// Get the Asset Lookup table.
const UlxAssetLookup *GetAssetLookup() const { return AssetLookup; }
// Transfer console output from the Luprex engine to unreal.
void UpdateConsoleOutput();
// Update the tangibles according to what Luprex tells us.
// This also includes calling 'AnimationQueueChanged' on all
// tangibles that have been changed.
void UpdateTangibles();
// Look for a tangible whose ID is equal to the current actor ID.
// Tell the player controller to possess that tangible.
void UpdatePossessedTangible();
// Call 'CalculateLookAt', but only if everything is valid.
// 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);
// The run function is called by a background thread
// to update luprex sockets and update luprex itself.
virtual uint32 Run() override;
// Get the current Luprex Game Mode Base, given a Context object.
static ALuprexGameModeBase *FromContext(const UObject *Context);
// Asset Lookup by Name.
UPROPERTY()
UlxAssetLookup *AssetLookup;
UPROPERTY()
UlxTangibleManager *TangibleManager;
// The actor that the player is looking at, current frame.
UPROPERTY()
FHitResult CurrentLookAt;
bool MustCallLookAtChanged;
// The sensitivity level at which a log message triggers a debugger breakpoint.
UPROPERTY(EditAnywhere, Category="Debugging Tools")
ElxLogVerbosity BreakToDebuggerLogVerbosity;
// The Luprex EngineWrapper, with a Mutex to protect it.
// To access it, construct a FlxLockedWrapper.
FlxLockableWrapper LockableWrapper;
// The Lua Call Assembly Buffer.
FlxStreamBuffer LuaCallBuffer;
// 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.
TUniquePtr<FlxSockets> Sockets;
// True if 'BeginPlay' has been successfully completed.
bool Playing;
// This is always true unless you use the debugger to set it to false.
bool TickEnabled;
// Current Player ID
int64 PlayerId;
// Amount of elapsed time since BeginPlay.
float EngineSeconds;
// When do we next rotate the cube.
float NextRotateCube;
// These allow us to pre-tick and post-tick.
FDelegateHandle OnWorldPreActorTickHandle;
FDelegateHandle OnWorldPostActorTickHandle;
// The device that implements BreakToDebuggerLogVerbosity, above.
TUniquePtr<FlxDebugBlueprintErrorsOutputDevice> BreakToDebuggerLogVerbosityDevice;
};