Files
integration/Source/Integration/LockedWrapper.h

147 lines
3.6 KiB
C++

////////////////////////////////////////////////////////////
//
// LockedWrapper.h
//
// Mutex-guarded access to the EngineWrapper.
//
////////////////////////////////////////////////////////////
#pragma once
#include "CoreMinimal.h"
#include "lpx-enginewrapper.hpp"
#include "Common.h"
////////////////////////////////////////////////////////////
//
// FlxLockableWrapper
//
// Contains the EngineWrapper and a Mutex to lock it.
// This class has no methods. To access the
// EngineWrapper, construct a FlxLockedWrapper.
//
////////////////////////////////////////////////////////////
class FlxLockableWrapper {
private:
FCriticalSection Mutex;
EngineWrapper Wrapper;
// Temporary buffers used only inside wrapper
// methods. Nothing persistent in these.
//
TArray<uint32> AQLenBuffer;
TArray<const char*> AQStrBuffer;
public:
friend class FlxLockedWrapper;
};
////////////////////////////////////////////////////////////
//
// FlxLockedWrapper
//
// RAII lock guard. The constructor claims the mutex,
// the destructor releases it. Use operator-> to
// access the EngineWrapper.
//
////////////////////////////////////////////////////////////
class FlxLockedWrapper {
private:
FlxLockableWrapper& Lockable;
// Called by luprex to output debugging messages.
// A thin wrapper around UE_LOG.
//
static void DPrintHook(const char *Msg, size_t Size);
public:
// Import these types into our namespace.
//
using IdArray = LpxCommonTypes::IdArray;
using IdView = LpxCommonTypes::IdView;
using StringViewVec = LpxCommonTypes::StringViewVec;
public:
// The constructor claims the mutex.
//
FlxLockedWrapper(FlxLockableWrapper& w) : Lockable(w) {
Lockable.Mutex.Lock();
}
// The destructor releases the mutex.
//
~FlxLockedWrapper() {
Lockable.Mutex.Unlock();
}
// Operator-> accesses the EngineWrapper.
//
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.
//
EngineWrapper* Get() {
return &Lockable.Wrapper;
}
// Initialize the engine wrapper if it's not
// already. All this does is open the DLL and
// hook up all the function pointers in the
// wrapper to point into the DLL.
//
void InitWrapper();
// 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);
};