Move a lot of EngineWrapper interfaces out of LuprexGameModeBase
This commit is contained in:
@@ -95,6 +95,29 @@ enum class ElxSuccessOrWrongType : uint8 {
|
|||||||
WrongType,
|
WrongType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ElxLuaSyntaxCheck
|
||||||
|
//
|
||||||
|
// Classifies console commands syntactically:
|
||||||
|
//
|
||||||
|
// SlashCommand: starts with a slash, not lua
|
||||||
|
// Whitespace: the input only contains whitespace
|
||||||
|
// ValidLua: the input is valid lua code
|
||||||
|
// TruncatedLua: the input is truncated
|
||||||
|
// InvalidLua: invalid lua
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class ElxLuaSyntaxCheck : uint8 {
|
||||||
|
SlashCommand,
|
||||||
|
Whitespace,
|
||||||
|
ValidLua,
|
||||||
|
TruncatedLua,
|
||||||
|
InvalidLua,
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Log Categories
|
// Log Categories
|
||||||
|
|||||||
@@ -83,3 +83,42 @@ StringViewVec FlxLockedWrapper::GetAnimationQueues(IdView ids) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElxLuaSyntaxCheck FlxLockedWrapper::ValidateLuaExpr(const FString &Code, FString &ErrorMessage) {
|
||||||
|
FTCHARToUTF8 UCode(*Code);
|
||||||
|
uint32_t retpklen;
|
||||||
|
const char *retpk;
|
||||||
|
Lockable.Wrapper.play_access(Get(), AccessKind::VALIDATE_LUA_EXPR, 0, UCode.Length(), UCode.Get(), &retpklen, &retpk);
|
||||||
|
ErrorMessage = FString(retpklen, (const UTF8CHAR*)retpk);
|
||||||
|
if (ErrorMessage.IsEmpty())
|
||||||
|
return ElxLuaSyntaxCheck::ValidLua;
|
||||||
|
if (ErrorMessage == TEXT("slash command"))
|
||||||
|
return ElxLuaSyntaxCheck::SlashCommand;
|
||||||
|
if (ErrorMessage == TEXT("white space"))
|
||||||
|
return ElxLuaSyntaxCheck::Whitespace;
|
||||||
|
if (ErrorMessage == TEXT("truncated lua"))
|
||||||
|
return ElxLuaSyntaxCheck::TruncatedLua;
|
||||||
|
return ElxLuaSyntaxCheck::InvalidLua;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlxLockedWrapper::ProbeLuaFunction(std::string_view datapk, int64 place_id, TFunction<void(std::string_view)> OnResult) {
|
||||||
|
if (place_id == 0) place_id = GetActor();
|
||||||
|
uint32_t retpklen;
|
||||||
|
const char *retpk;
|
||||||
|
Lockable.Wrapper.play_access(Get(), AccessKind::PROBE_LUA_CALL, place_id, datapk.size(), datapk.data(), &retpklen, &retpk);
|
||||||
|
OnResult(std::string_view(retpk, retpklen));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlxLockedWrapper::InvokeLuaFunction(std::string_view datapk, int64 place_id) {
|
||||||
|
if (place_id == 0) place_id = GetActor();
|
||||||
|
uint32_t retpklen;
|
||||||
|
const char *retpk;
|
||||||
|
Lockable.Wrapper.play_access(Get(), AccessKind::INVOKE_LUA_CALL, place_id, datapk.size(), datapk.data(), &retpklen, &retpk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlxLockedWrapper::InvokeLuaExpr(const FString &Code) {
|
||||||
|
FTCHARToUTF8 UCode(*Code);
|
||||||
|
uint32_t retpklen;
|
||||||
|
const char *retpk;
|
||||||
|
Lockable.Wrapper.play_access(Get(), AccessKind::INVOKE_LUA_EXPR, 0, UCode.Length(), UCode.Get(), &retpklen, &retpk);
|
||||||
|
}
|
||||||
|
|||||||
@@ -119,4 +119,28 @@ public:
|
|||||||
// next time you call this.
|
// next time you call this.
|
||||||
//
|
//
|
||||||
StringViewVec GetAnimationQueues(IdView ids);
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include "LuaCall.h"
|
#include "LuaCall.h"
|
||||||
#include "LuprexGameModeBase.h"
|
#include "LuprexGameModeBase.h"
|
||||||
|
#include "Tangible.h"
|
||||||
#include "StringDecoder.h"
|
#include "StringDecoder.h"
|
||||||
|
|
||||||
#include "EdGraphSchema_K2.h"
|
#include "EdGraphSchema_K2.h"
|
||||||
@@ -196,51 +197,30 @@ FString UlxLuaCallLibrary::AllFunctionsWithPrefix(const TCHAR *Prefix)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// General Lua-Callable functions of the Lua Call Library.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void UlxLuaCallLibrary::ValidateLuaExpr(
|
|
||||||
ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code)
|
|
||||||
{
|
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
|
||||||
ErrorMessage = mode->ValidateLuaExpr(Code);
|
|
||||||
if (ErrorMessage.IsEmpty())
|
|
||||||
{
|
|
||||||
Status = ElxLuaSyntaxCheck::ValidLua;
|
|
||||||
}
|
|
||||||
else if (ErrorMessage == TEXT("slash command"))
|
|
||||||
{
|
|
||||||
Status = ElxLuaSyntaxCheck::SlashCommand;
|
|
||||||
}
|
|
||||||
else if (ErrorMessage == TEXT("white space"))
|
|
||||||
{
|
|
||||||
Status = ElxLuaSyntaxCheck::Whitespace;
|
|
||||||
}
|
|
||||||
else if (ErrorMessage == TEXT("truncated lua"))
|
|
||||||
{
|
|
||||||
Status = ElxLuaSyntaxCheck::TruncatedLua;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = ElxLuaSyntaxCheck::InvalidLua;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UlxLuaCallLibrary::InvokeLuaExpr(UObject *context, const FString &Code)
|
void UlxLuaCallLibrary::InvokeLuaExpr(UObject *context, const FString &Code)
|
||||||
{
|
{
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
mode->InvokeLuaExpr(Code);
|
FlxLockedWrapper w(mode->GetLockableWrapper());
|
||||||
|
w.InvokeLuaExpr(Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve an AActor to a tangible place_id.
|
||||||
|
// Returns 0 if place is null (meaning "use current
|
||||||
|
// actor"), or the tangible ID if found. Returns -1
|
||||||
|
// if place is non-null but has no tangible.
|
||||||
|
//
|
||||||
|
static int64 ResolvePlaceId(AActor *place)
|
||||||
|
{
|
||||||
|
if (place == nullptr) return 0;
|
||||||
|
UlxTangible *tan = UlxTangible::GetActorTangibleOrLog(place);
|
||||||
|
return tan ? tan->TangibleId : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallBegin(UObject *context, const FString &cname, const FString &fname)
|
void UlxLuaCallLibrary::LuaCallBegin(UObject *context, const FString &cname, const FString &fname)
|
||||||
{
|
{
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
mode->LuaCallBegin();
|
sb.clear();
|
||||||
sb.write_string(cname);
|
sb.write_string(cname);
|
||||||
sb.write_string(fname);
|
sb.write_string(fname);
|
||||||
}
|
}
|
||||||
@@ -248,19 +228,33 @@ void UlxLuaCallLibrary::LuaCallBegin(UObject *context, const FString &cname, con
|
|||||||
void UlxLuaCallLibrary::LuaCallInvoke(UObject *context, AActor *place)
|
void UlxLuaCallLibrary::LuaCallInvoke(UObject *context, AActor *place)
|
||||||
{
|
{
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
mode->LuaCallEnd(AccessKind::INVOKE_LUA_CALL, place);
|
int64 place_id = ResolvePlaceId(place);
|
||||||
|
if (place_id < 0) { sb.clear(); return; }
|
||||||
|
FlxLockedWrapper w(mode->GetLockableWrapper());
|
||||||
|
w.InvokeLuaFunction(sb.view(), place_id);
|
||||||
|
sb.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UlxLuaCallLibrary::LuaCallProbe(UObject *context, AActor *place, UlxLuaValues *&ReturnArray)
|
bool UlxLuaCallLibrary::LuaCallProbe(UObject *context, AActor *place, UlxLuaValues *&ReturnArray)
|
||||||
{
|
{
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return false;
|
if (NotInitialized(sb)) return false;
|
||||||
ReturnArray = mode->LuaCallEnd(AccessKind::PROBE_LUA_CALL, place);
|
int64 place_id = ResolvePlaceId(place);
|
||||||
if ((ReturnArray == nullptr) || (ReturnArray->Length() < 1))
|
if (place_id < 0) {
|
||||||
|
sb.clear();
|
||||||
|
ReturnArray = NewObject<UlxLuaValues>(mode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ReturnArray = NewObject<UlxLuaValues>(mode);
|
||||||
|
FlxLockedWrapper w(mode->GetLockableWrapper());
|
||||||
|
w.ProbeLuaFunction(sb.view(), place_id, [&](std::string_view retpk) {
|
||||||
|
ReturnArray->Initialize(retpk);
|
||||||
|
});
|
||||||
|
sb.clear();
|
||||||
|
if (ReturnArray->Length() < 1)
|
||||||
{
|
{
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("corruption in lua_probe"));
|
UE_LOG(LogLuprexIntegration, Error, TEXT("corruption in lua_probe"));
|
||||||
ReturnArray = nullptr;
|
ReturnArray = nullptr;
|
||||||
@@ -292,7 +286,7 @@ bool UlxLuaCallLibrary::LuaCallProbe(UObject *context, AActor *place, UlxLuaValu
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_string(UObject *context, const FString &pstring) {
|
void UlxLuaCallLibrary::LuaCallArgument_string(UObject *context, const FString &pstring) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::STRING);
|
sb.write_simple_dynamic_tag(LuaValueType::STRING);
|
||||||
sb.write_string(pstring);
|
sb.write_string(pstring);
|
||||||
@@ -307,7 +301,7 @@ void UlxLuaCallLibrary::LuaCallArgument_name(UObject *context, const FName &pnam
|
|||||||
UE_LOG(LogBlueprint, Error, TEXT("Names passed to lua must be short, and must contain only lowercase and digits"));
|
UE_LOG(LogBlueprint, Error, TEXT("Names passed to lua must be short, and must contain only lowercase and digits"));
|
||||||
}
|
}
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::TOKEN);
|
sb.write_simple_dynamic_tag(LuaValueType::TOKEN);
|
||||||
sb.write_string(namestr);
|
sb.write_string(namestr);
|
||||||
@@ -315,7 +309,7 @@ void UlxLuaCallLibrary::LuaCallArgument_name(UObject *context, const FName &pnam
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_float(UObject *context, double pfloat) {
|
void UlxLuaCallLibrary::LuaCallArgument_float(UObject *context, double pfloat) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
|
sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
|
||||||
sb.write_double(pfloat);
|
sb.write_double(pfloat);
|
||||||
@@ -323,7 +317,7 @@ void UlxLuaCallLibrary::LuaCallArgument_float(UObject *context, double pfloat) {
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_int(UObject *context, int value) {
|
void UlxLuaCallLibrary::LuaCallArgument_int(UObject *context, int value) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
|
sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
|
||||||
sb.write_double(value);
|
sb.write_double(value);
|
||||||
@@ -331,7 +325,7 @@ void UlxLuaCallLibrary::LuaCallArgument_int(UObject *context, int value) {
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_vector(UObject *context, const FVector &pvector) {
|
void UlxLuaCallLibrary::LuaCallArgument_vector(UObject *context, const FVector &pvector) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
|
sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
|
||||||
sb.write_fvector(pvector);
|
sb.write_fvector(pvector);
|
||||||
@@ -339,7 +333,7 @@ void UlxLuaCallLibrary::LuaCallArgument_vector(UObject *context, const FVector &
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_vector2d(UObject *context, const FVector2D &pvector) {
|
void UlxLuaCallLibrary::LuaCallArgument_vector2d(UObject *context, const FVector2D &pvector) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
|
sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
|
||||||
sb.write_double(pvector.X);
|
sb.write_double(pvector.X);
|
||||||
@@ -349,7 +343,7 @@ void UlxLuaCallLibrary::LuaCallArgument_vector2d(UObject *context, const FVector
|
|||||||
|
|
||||||
void UlxLuaCallLibrary::LuaCallArgument_boolean(UObject *context, bool pbool) {
|
void UlxLuaCallLibrary::LuaCallArgument_boolean(UObject *context, bool pbool) {
|
||||||
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
|
FlxStreamBuffer &sb = mode->GetLuaCallBuffer();
|
||||||
if (NotInitialized(sb)) return;
|
if (NotInitialized(sb)) return;
|
||||||
sb.write_simple_dynamic_tag(LuaValueType::BOOLEAN);
|
sb.write_simple_dynamic_tag(LuaValueType::BOOLEAN);
|
||||||
sb.write_bool(pbool);
|
sb.write_bool(pbool);
|
||||||
|
|||||||
@@ -23,29 +23,6 @@
|
|||||||
|
|
||||||
class UlxLuaValues;
|
class UlxLuaValues;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// ElxLuaSyntaxCheck
|
|
||||||
//
|
|
||||||
// Classifies console commands syntactically:
|
|
||||||
//
|
|
||||||
// SlashCommand: starts with a slash, not lua
|
|
||||||
// Whitespace: the input only contains whitespace
|
|
||||||
// ValidLua: the input is valid lua code
|
|
||||||
// TruncatedLua: the input is truncated
|
|
||||||
// InvalidLua: invalid lua
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
|
||||||
enum class ElxLuaSyntaxCheck : uint8 {
|
|
||||||
SlashCommand,
|
|
||||||
Whitespace,
|
|
||||||
ValidLua,
|
|
||||||
TruncatedLua,
|
|
||||||
InvalidLua,
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// FlxParsedProto
|
// FlxParsedProto
|
||||||
@@ -158,16 +135,6 @@ public:
|
|||||||
static FString AllKnownReturnValueTypes() { return AllFunctionsWithPrefix(TEXT("LuaCallReturnValue_")); }
|
static FString AllKnownReturnValueTypes() { return AllFunctionsWithPrefix(TEXT("LuaCallReturnValue_")); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Syntactically validate lua code. Parses the
|
|
||||||
// code and returns an error message. If the code
|
|
||||||
// is error-free, the error message is empty.
|
|
||||||
//
|
|
||||||
// TODO: This doesn't belong here. This library
|
|
||||||
// is for LuaCallNode's internal implementation.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function")
|
|
||||||
static void ValidateLuaExpr(ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Functions that initiate and complete the lua call.
|
// Functions that initiate and complete the lua call.
|
||||||
|
|||||||
@@ -187,58 +187,6 @@ void ALuprexGameModeBase::UpdatePossessedTangible() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(AccessKind kind, int64 place_id) {
|
|
||||||
std::string_view datapk = LuaCallBuffer.view();
|
|
||||||
FlxLockedWrapper w(LockableWrapper);
|
|
||||||
if (place_id == 0) place_id = w.GetActor();
|
|
||||||
uint32_t retpklen;
|
|
||||||
const char *retpk;
|
|
||||||
w->play_access(w.Get(), kind, place_id, datapk.size(), datapk.data(), &retpklen, &retpk);
|
|
||||||
if (kind == AccessKind::PROBE_LUA_CALL)
|
|
||||||
{
|
|
||||||
UlxLuaValues *Result = NewObject<UlxLuaValues>(this);
|
|
||||||
Result->Initialize(std::string_view(retpk, retpklen));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
else return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(AccessKind kind) {
|
|
||||||
return LuaCallEnd(kind, int64(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
UlxLuaValues *ALuprexGameModeBase::LuaCallEnd(AccessKind kind, AActor *place) {
|
|
||||||
if (place == nullptr) {
|
|
||||||
return LuaCallEnd(kind, int64(0));
|
|
||||||
} else {
|
|
||||||
UlxTangible *tan = UlxTangible::GetActorTangibleOrLog(place);
|
|
||||||
if (tan == nullptr) {
|
|
||||||
return NewObject<UlxLuaValues>(this);
|
|
||||||
} else {
|
|
||||||
return LuaCallEnd(kind, tan->TangibleId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FString ALuprexGameModeBase::ValidateLuaExpr(const FString &Code)
|
|
||||||
{
|
|
||||||
FTCHARToUTF8 UCode(*Code);
|
|
||||||
FlxLockedWrapper w(LockableWrapper);
|
|
||||||
uint32_t retpklen;
|
|
||||||
const char *retpk;
|
|
||||||
w->play_access(w.Get(), AccessKind::VALIDATE_LUA_EXPR, 0, UCode.Length(), UCode.Get(), &retpklen, &retpk);
|
|
||||||
FString Result(retpklen, (const UTF8CHAR*)retpk);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALuprexGameModeBase::InvokeLuaExpr(const FString &Code)
|
|
||||||
{
|
|
||||||
FTCHARToUTF8 UCode(*Code);
|
|
||||||
FlxLockedWrapper w(LockableWrapper);
|
|
||||||
uint32_t retpklen;
|
|
||||||
const char *retpk;
|
|
||||||
w->play_access(w.Get(), AccessKind::INVOKE_LUA_EXPR, 0, UCode.Length(), UCode.Get(), &retpklen, &retpk);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALuprexGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds)
|
void ALuprexGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,38 +82,12 @@ public:
|
|||||||
void LookAtChanged();
|
void LookAtChanged();
|
||||||
|
|
||||||
|
|
||||||
// Assemble a lua call. Note that this is the lowest-level interface.
|
// The Lua Call Assembly Buffer. Used by
|
||||||
// These functions are wrapped by the functions in UlxLuaCallLibrary,
|
// UlxLuaCallLibrary to build up a call across
|
||||||
// and those in turn are wrapped by the K2Node "LuaInvoke" and "LuaProbe".
|
// multiple UFUNCTION invocations.
|
||||||
//
|
//
|
||||||
// At this level, the process of calling Lua is:
|
FlxStreamBuffer &GetLuaCallBuffer() { return LuaCallBuffer; }
|
||||||
//
|
|
||||||
// * 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.
|
// Get the Asset Lookup table.
|
||||||
const UlxAssetLookup *GetAssetLookup() const { return AssetLookup; }
|
const UlxAssetLookup *GetAssetLookup() const { return AssetLookup; }
|
||||||
@@ -164,8 +138,13 @@ public:
|
|||||||
|
|
||||||
// The Luprex EngineWrapper, with a Mutex to protect it.
|
// The Luprex EngineWrapper, with a Mutex to protect it.
|
||||||
// To access it, construct a FlxLockedWrapper.
|
// To access it, construct a FlxLockedWrapper.
|
||||||
|
//
|
||||||
FlxLockableWrapper LockableWrapper;
|
FlxLockableWrapper LockableWrapper;
|
||||||
|
|
||||||
|
// Get the LockableWrapper.
|
||||||
|
//
|
||||||
|
FlxLockableWrapper& GetLockableWrapper() { return LockableWrapper; }
|
||||||
|
|
||||||
// The Lua Call Assembly Buffer.
|
// The Lua Call Assembly Buffer.
|
||||||
FlxStreamBuffer LuaCallBuffer;
|
FlxStreamBuffer LuaCallBuffer;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "UtilityLibrary.h"
|
#include "UtilityLibrary.h"
|
||||||
|
#include "LuprexGameModeBase.h"
|
||||||
#include "GameFramework/PlayerController.h"
|
#include "GameFramework/PlayerController.h"
|
||||||
#include "EnhancedInputSubsystems.h"
|
#include "EnhancedInputSubsystems.h"
|
||||||
#include "Kismet/KismetSystemLibrary.h"
|
#include "Kismet/KismetSystemLibrary.h"
|
||||||
@@ -251,3 +252,11 @@ FVector UlxUtilityLibrary::GetActorForwardVelocity(const AActor *Actor, double S
|
|||||||
}
|
}
|
||||||
return Forward * Speed;
|
return Forward * Speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UlxUtilityLibrary::ValidateLuaExpr(
|
||||||
|
ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code)
|
||||||
|
{
|
||||||
|
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
|
||||||
|
FlxLockedWrapper w(mode->GetLockableWrapper());
|
||||||
|
Status = w.ValidateLuaExpr(Code, ErrorMessage);
|
||||||
|
}
|
||||||
|
|||||||
@@ -165,4 +165,11 @@ public:
|
|||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Utility", meta = (DefaultToSelf = "Actor"))
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Utility", meta = (DefaultToSelf = "Actor"))
|
||||||
static FVector GetActorForwardVelocity(const AActor *Actor, double Speed = 1.0, bool bSnapToXY = false);
|
static FVector GetActorForwardVelocity(const AActor *Actor, double Speed = 1.0, bool bSnapToXY = false);
|
||||||
|
|
||||||
|
// Syntactically validate lua code. Parses the
|
||||||
|
// code and returns an error message. If the code
|
||||||
|
// is error-free, the error message is empty.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Utility")
|
||||||
|
static void ValidateLuaExpr(ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ end
|
|||||||
|
|
||||||
function engio.move(action, xyz, facing)
|
function engio.move(action, xyz, facing)
|
||||||
-- todo: sanity check the parameters.
|
-- todo: sanity check the parameters.
|
||||||
-- dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
|
dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
|
||||||
tangible.animate{tan=actor, anim={action=action, interactive=true, xyz=xyz, facing=facing}}
|
tangible.animate{tan=actor, anim={action=action, interactive=true, xyz=xyz, facing=facing}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user