From 4023d19247a1d2bcc6e6582754236f55cac63db5 Mon Sep 17 00:00:00 2001 From: jyelon Date: Wed, 5 Feb 2025 16:08:34 -0500 Subject: [PATCH] Add support for LuaToken to the LuaCall unreal pipeline --- Source/Integration/LuaCall.cpp | 21 ++++++++++++++++++--- Source/Integration/LuaCall.h | 9 ++++++++- Source/Integration/StringDecoder.h | 15 +++++++++++++++ luprex/cpp/core/world-core.cpp | 27 ++++++++++++++++++--------- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/Source/Integration/LuaCall.cpp b/Source/Integration/LuaCall.cpp index fa0d0467..4fae279f 100644 --- a/Source/Integration/LuaCall.cpp +++ b/Source/Integration/LuaCall.cpp @@ -30,6 +30,13 @@ void UlxLuaCallLibrary::LuaCallAddStringParameter(UObject *context, const FStrin sb.write_string(pstring); } +void UlxLuaCallLibrary::LuaCallAddNameParameter(UObject *context, const FName &pname) { + AIntegrationGameModeBase *mode = AIntegrationGameModeBase::GetFromContext(context); + FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); + CheckNotEmpty(sb); + sb.write_simple_dynamic_tag(SimpleDynamicTag::STRING); + sb.write_fname(pname); +} void UlxLuaCallLibrary::LuaCallAddFloatParameter(UObject *context, double pfloat) { AIntegrationGameModeBase *mode = AIntegrationGameModeBase::GetFromContext(context); @@ -47,7 +54,7 @@ void UlxLuaCallLibrary::LuaCallAddVectorParameter(UObject *context, const FVecto sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR); sb.write_fvector(pvector); } - + void UlxLuaCallLibrary::LuaCallAddBooleanParameter(UObject *context, bool pbool) { AIntegrationGameModeBase *mode = AIntegrationGameModeBase::GetFromContext(context); @@ -98,6 +105,7 @@ ELpxSimpleDynamicTag UlxLuaCallLibrary::LuaCallNextResultType(UObject *context) sb.unread_to(total_reads); switch (tag) { case SimpleDynamicTag::STRING: return ELpxSimpleDynamicTag::String; + case SimpleDynamicTag::TOKEN: return ELpxSimpleDynamicTag::Name; case SimpleDynamicTag::NUMBER: return ELpxSimpleDynamicTag::Float; case SimpleDynamicTag::VECTOR: return ELpxSimpleDynamicTag::Vector; case SimpleDynamicTag::BOOLEAN: return ELpxSimpleDynamicTag::Boolean; @@ -110,8 +118,15 @@ FString UlxLuaCallLibrary::LuaCallGetStringResult(UObject *context) { FlxStreamBuffer &sb = mode->LuaCallGetResult(); SimpleDynamicTag tag = sb.read_simple_dynamic_tag(); if (tag != SimpleDynamicTag::STRING) FatalBlueprintError(TEXT("expected lua to return a string")); - std::string_view s = sb.read_string_view(); - return FString(s.size(), (const UTF8CHAR *)s.data()); + return sb.read_fstring(); +} + +FName UlxLuaCallLibrary::LuaCallGetNameResult(UObject *context) { + AIntegrationGameModeBase *mode = AIntegrationGameModeBase::GetFromContext(context); + FlxStreamBuffer &sb = mode->LuaCallGetResult(); + SimpleDynamicTag tag = sb.read_simple_dynamic_tag(); + if (tag != SimpleDynamicTag::TOKEN) FatalBlueprintError(TEXT("expected lua to return a name")); + return sb.read_fname(); } double UlxLuaCallLibrary::LuaCallGetFloatResult(UObject *context) { diff --git a/Source/Integration/LuaCall.h b/Source/Integration/LuaCall.h index 06775473..0c54dd32 100644 --- a/Source/Integration/LuaCall.h +++ b/Source/Integration/LuaCall.h @@ -7,6 +7,7 @@ UENUM(BlueprintType) enum class ELpxSimpleDynamicTag : uint8 { None, String, + Name, Float, Boolean, Vector @@ -31,7 +32,10 @@ public: UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") static void LuaCallAddStringParameter(UObject *context, const FString &pstring); - + + UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") + static void LuaCallAddNameParameter(UObject *context, const FName &pname); + UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") static void LuaCallAddFloatParameter(UObject *context, double pfloat); @@ -56,6 +60,9 @@ public: UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") static FString LuaCallGetStringResult(UObject *context); + UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") + static FName LuaCallGetNameResult(UObject *context); + UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Call Lua Function") static double LuaCallGetFloatResult(UObject *context); diff --git a/Source/Integration/StringDecoder.h b/Source/Integration/StringDecoder.h index 5cea30e9..e1850b94 100644 --- a/Source/Integration/StringDecoder.h +++ b/Source/Integration/StringDecoder.h @@ -37,6 +37,11 @@ public: write_string(std::string_view(utf8str.Get(), utf8str.Length())); } + void write_fname(const FName &name) { + FTCHARToUTF8 utf8str(name.ToString()); + write_string(std::string_view(utf8str.Get(), utf8str.Length())); + } + void write_string(const char *s) { write_string(std::string_view(s)); } @@ -53,5 +58,15 @@ public: double z = read_double(); return FVector(x, y, z); } + + FString read_fstring() { + std::string_view s = read_string_view(); + return FString(s.size(), (const UTF8CHAR *)s.data()); + } + + FName read_fname() { + std::string_view s = read_string_view(); + return FName(s.size(), (const UTF8CHAR *)s.data(), FNAME_Add); + } }; diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index e2a33b4e..fd9d42a5 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -13,6 +13,16 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) { SimpleDynamicTag type = sb->read_simple_dynamic_tag(); switch (type) { + case SimpleDynamicTag::STRING: { + std::string_view s = sb->read_string_view(); + lua_pushlstring(L, s.data(), s.size()); + break; + } + case SimpleDynamicTag::TOKEN: { + LuaToken token(sb->read_string_view()); + lua_pushlightuserdata(L, token.voidvalue()); + break; + } case SimpleDynamicTag::NUMBER: { lua_pushnumber(L, sb->read_double()); break; @@ -21,11 +31,6 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) { lua_pushboolean(L, sb->read_bool() ? 1:0); break; } - case SimpleDynamicTag::STRING: { - std::string_view s = sb->read_string_view(); - lua_pushlstring(L, s.data(), s.size()); - break; - } case SimpleDynamicTag::VECTOR: { double x = sb->read_double(); double y = sb->read_double(); @@ -46,14 +51,18 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) { // Given a lua value, try to pack it into the stream buffer as a simple dynamic. bool encode_simple_dynamic(LuaCoreStack &LS, LuaSlot &slot, StreamBuffer *sb) { switch (LS.type(slot)) { - case LUA_TNUMBER: - sb->write_simple_dynamic_tag(SimpleDynamicTag::NUMBER); - sb->write_double(LS.cknumber(slot)); - return true; case LUA_TSTRING: sb->write_simple_dynamic_tag(SimpleDynamicTag::STRING); sb->write_string(LS.ckstringview(slot)); return true; + case LUA_TLIGHTUSERDATA: + sb->write_simple_dynamic_tag(SimpleDynamicTag::TOKEN); + sb->write_string(LS.cktoken(slot).str()); + return true; + case LUA_TNUMBER: + sb->write_simple_dynamic_tag(SimpleDynamicTag::NUMBER); + sb->write_double(LS.cknumber(slot)); + return true; case LUA_TBOOLEAN: sb->write_simple_dynamic_tag(SimpleDynamicTag::BOOLEAN); sb->write_bool(LS.ckboolean(slot));