Files
integration/Source/Integration/LockedWrapper.h

156 lines
3.9 KiB
C
Raw Normal View History

////////////////////////////////////////////////////////////
//
// LockedWrapper.h
//
// Mutex-guarded access to the EngineWrapper.
//
////////////////////////////////////////////////////////////
2023-09-03 02:01:32 -04:00
#pragma once
#include "CoreMinimal.h"
#include "lpx-enginewrapper.hpp"
2026-02-09 13:54:00 -05:00
#include "Common.h"
#include "StreamBuffer.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "LockedWrapper.generated.h"
2023-09-03 02:01:32 -04:00
////////////////////////////////////////////////////////////
//
// UlxEngineWrapper
//
// GameInstanceSubsystem that owns the EngineWrapper and
// a Mutex to lock it. To access the EngineWrapper,
// construct a FlxLockedWrapper.
2023-09-03 02:01:32 -04:00
//
////////////////////////////////////////////////////////////
UCLASS()
class INTEGRATION_API UlxEngineWrapper : public UGameInstanceSubsystem {
GENERATED_BODY()
2023-09-03 02:01:32 -04:00
private:
static UlxEngineWrapper* Instance;
// Called by luprex to output debugging messages.
// A thin wrapper around UE_LOG.
//
static void DPrintHook(const char *Msg, size_t Size);
2023-09-03 02:01:32 -04:00
FCriticalSection Mutex;
EngineWrapper Wrapper;
// The Lua Call Assembly Buffer. Used to build up
// a call across multiple UFUNCTION invocations.
// Only accessed from the game thread.
//
FlxStreamBuffer LuaCallBuffer;
2023-09-03 02:01:32 -04:00
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
// Get the Lua Call Assembly Buffer.
// Only called from the game thread.
//
static FlxStreamBuffer& GetLuaCallBuffer() { return Instance->LuaCallBuffer; }
2023-09-15 13:28:18 -04:00
friend class FlxLockedWrapper;
2023-09-03 02:01:32 -04:00
};
////////////////////////////////////////////////////////////
//
// FlxLockedWrapper
//
// RAII lock guard. The constructor claims the mutex,
// the destructor releases it. Use operator-> to
// access the EngineWrapper.
//
////////////////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
class FlxLockedWrapper {
2023-09-03 02:01:32 -04:00
private:
UlxEngineWrapper& Lockable;
public:
// Import these types into our namespace.
//
2026-02-09 13:54:00 -05:00
using IdArray = LpxCommonTypes::IdArray;
using IdView = LpxCommonTypes::IdView;
using StringViewVec = LpxCommonTypes::StringViewVec;
2023-09-03 02:01:32 -04:00
public:
// The constructor claims the mutex.
//
FlxLockedWrapper() : Lockable(*UlxEngineWrapper::Instance) {
2023-09-03 02:01:32 -04:00
Lockable.Mutex.Lock();
}
// The destructor releases the mutex.
//
2023-09-15 13:28:18 -04:00
~FlxLockedWrapper() {
2023-09-03 02:01:32 -04:00
Lockable.Mutex.Unlock();
}
// Operator-> accesses the EngineWrapper.
//
2023-09-03 02:01:32 -04:00
EngineWrapper* operator ->() {
return &Lockable.Wrapper;
}
// Get a pointer to the EngineWrapper. Not very
// safe because you could keep the pointer after
// the LockedWrapper is destroyed. Don't do that.
//
2023-09-03 02:01:32 -04:00
EngineWrapper* Get() {
return &Lockable.Wrapper;
}
// Fetch Stdout as a string.
//
FString ChannelPrints();
// Get the current Actor ID.
//
int64 GetActor();
// Get the list of tangibles near the actor.
//
// This function is fast but not free. You should
// fetch this once per frame and then store the
// IdView somewhere (like in the TangibleManager).
//
IdView GetNear(int64 id, double rx, double ry, double rz);
// Get animation queues.
//
// The array returned by this is valid until the
// next time you call this.
//
StringViewVec GetAnimationQueues(IdView ids);
// Call a Lua function. The datapk contains the
// serialized class name, function name, and
// arguments. If place_id is 0, defaults to the
// current actor. The OnResult callback receives
// the raw return data while the lock is held;
// use it to copy the data before it goes away.
//
void ProbeLuaFunction(std::string_view datapk, int64 place_id, TFunction<void(std::string_view)> OnResult);
// Invoke a Lua function (fire-and-forget, no
// return values).
//
void InvokeLuaFunction(std::string_view datapk, int64 place_id);
// Validate a Lua expression. Returns a syntax
// classification and an error message. The error
// message is empty if the code is valid.
//
ElxLuaSyntaxCheck ValidateLuaExpr(const FString &Code, FString &ErrorMessage);
// Execute a Lua expression.
//
void InvokeLuaExpr(const FString &Code);
2023-09-03 02:01:32 -04:00
};