diff --git a/Content/Luprex/lxGameMode.uasset b/Content/Luprex/lxGameMode.uasset index 8886427d..62fc6889 100644 --- a/Content/Luprex/lxGameMode.uasset +++ b/Content/Luprex/lxGameMode.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96fef1fc352a124bcd6e59f99eca20f71ba45983cd45291956004d01b511d219 -size 127513 +oid sha256:fdc80c07df541ad2254d1ccb085d08ee5ab903204c067a775e4032b9f9e6ed39 +size 120192 diff --git a/Source/Integration/FormatError.cpp b/Source/Integration/FormatError.cpp index 6227bccb..c32c2a79 100644 --- a/Source/Integration/FormatError.cpp +++ b/Source/Integration/FormatError.cpp @@ -95,7 +95,7 @@ void UK2Node_FormatMessage::CreateCorrectPins() if (FindPin(FormatPinName, EGPD_Input) == nullptr) { UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FormatPinName); - P->DefaultValue = TEXT("Error Message"); + P->DefaultValue = TEXT("Message"); } // If this is a FormatMessage node, create a pin to output the result as text. diff --git a/Source/Integration/LuaCall.h b/Source/Integration/LuaCall.h index fa1f3819..043cdbdd 100644 --- a/Source/Integration/LuaCall.h +++ b/Source/Integration/LuaCall.h @@ -5,24 +5,6 @@ #include "LuaCall.generated.h" -///////////////////////////////////////////////////////////////// -// -// These are the types that can actually be packed into -// an argument or return value buffer. Any other type is -// subject to conversion before packing. -// -///////////////////////////////////////////////////////////////// - -UENUM(BlueprintType) -enum class ELpxSimpleDynamicTag : uint8 { - None, - String, - Name, - Float, - Boolean, - Vector -}; - ///////////////////////////////////////////////////////////////// // // This is a little parser that parses Lua function 'prototypes'. diff --git a/Source/Integration/StringDecoder.cpp b/Source/Integration/StringDecoder.cpp index a25b4a7a..5ce873cd 100644 --- a/Source/Integration/StringDecoder.cpp +++ b/Source/Integration/StringDecoder.cpp @@ -1,2 +1,119 @@ #include "StringDecoder.h" + +void UlxLuaValues::Empty() +{ + Serialized.clear(); + Types.Empty(); + Data.Empty(); + Cursor = 0; +} + +bool UlxLuaValues::Initialize(std::string_view data) +{ + Empty(); + Serialized = data; + const char *SerializedChar = &Serialized[0]; + + FlxStreamBuffer Decoder(Serialized); + + while (!Decoder.empty()) + { + SimpleDynamicTag Tag = Decoder.read_simple_dynamic_tag(); + + int64 Pos = Decoder.total_reads(); + ELxLuaValueType Type; + switch (Tag) + { + case SimpleDynamicTag::BOOLEAN: Type=ELxLuaValueType::Boolean; Decoder.read_bool(); break; + case SimpleDynamicTag::NUMBER: Type=ELxLuaValueType::Float; Decoder.read_double(); break; + case SimpleDynamicTag::STRING: Type=ELxLuaValueType::String; Decoder.read_string_view(); break; + case SimpleDynamicTag::TOKEN: Type=ELxLuaValueType::Name; Decoder.read_string_view(); break; + case SimpleDynamicTag::VECTOR: Type=ELxLuaValueType::Vector; Decoder.read_fvector(); break; + default: { + Empty(); + return false; + } + } + int64 Pos2 = Decoder.total_reads(); + Types.Add(Type); + Data.Add(std::string_view(SerializedChar + Pos, Pos2 - Pos)); + } + return true; +} + +bool UlxLuaValues::CheckType(ELxLuaValueType Type, ELxLuaValueType Desired) +{ + if (Type != Desired) + { + FString TypeName = StaticEnum()->GetDisplayNameTextByValue(int64(Type)).ToString(); + FString DesiredName = StaticEnum()->GetDisplayNameTextByValue(int64(Desired)).ToString(); + UE_LOG(LogBlueprint, Error, TEXT("Expected a value of type %s, but found %s instead."), *DesiredName, *TypeName); + return false; + } + return true; +} + +ELxLuaValueType UlxLuaValues::GetType(int n) const +{ + if (n < 0) return ELxLuaValueType::None; + if (n >= Types.Num()) return ELxLuaValueType::None; + return Types[Cursor]; +} + +// +// Get the Nth value in the array. Array bounds-checking +// is handled by 'GetType', which returns 'None' for out-of-bounds +// accesses. +// + +FString UlxLuaValues::GetString(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::String)) return FString(); + FlxStreamBuffer Decoder(Data[n]); + return Decoder.read_fstring(); +} + +FName UlxLuaValues::GetName(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Name)) return FName(); + FlxStreamBuffer Decoder(Data[n]); + return Decoder.read_fname(); +} + +double UlxLuaValues::GetFloat(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Float)) return 0.0; + FlxStreamBuffer Decoder(Data[n]); + return Decoder.read_double(); +} + +int UlxLuaValues::GetInt(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Float)) return 0; + FlxStreamBuffer Decoder(Data[n]); + return int(Decoder.read_double()); +} + +FVector UlxLuaValues::GetVector(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Vector)) return FVector(); + FlxStreamBuffer Decoder(Data[n]); + return Decoder.read_fvector(); +} + +FVector2D UlxLuaValues::GetVector2D(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Vector)) return FVector2D(); + FlxStreamBuffer Decoder(Data[n]); + FVector v = Decoder.read_fvector(); + return FVector2D(v.X, v.Y); +} + +bool UlxLuaValues::GetBoolean(int n) const +{ + if (!CheckType(GetType(n), ELxLuaValueType::Boolean)) return false; + FlxStreamBuffer Decoder(Data[n]); + return Decoder.read_bool(); +} + diff --git a/Source/Integration/StringDecoder.h b/Source/Integration/StringDecoder.h index e1850b94..01122a79 100644 --- a/Source/Integration/StringDecoder.h +++ b/Source/Integration/StringDecoder.h @@ -3,8 +3,7 @@ #include "CoreMinimal.h" #include "lpx-basebuffer.hpp" - -using FlxSimpleDynamic = SimpleDynamic; +#include "StringDecoder.generated.h" class FlxStreamBufferCore { private: @@ -70,3 +69,137 @@ public: } }; +///////////////////////////////////////////////////////////////// +// +// These are the types that can actually be packed into +// a serialized buffer. +// +///////////////////////////////////////////////////////////////// + +UENUM(BlueprintType) +enum class ELxLuaValueType : uint8 { + None, + String, + Name, + Float, + Boolean, + Vector +}; + + +///////////////////////////////////////////////////////////////// +// +// This class stores an array of values that were returned by Lua. +// +///////////////////////////////////////////////////////////////// + +UCLASS(MinimalAPI) +class UlxLuaValues : public UObject +{ + GENERATED_BODY() + +private: + // The raw serialized data returned by Lua. + // + std::string Serialized; + + // For each chunk, the type of the chunk. + // + TArray Types; + + // For each chunk, a pointer to the serialized data. + // + TArray Data; + + // The current cursor. + // + int Cursor; + +private: + // Clear everything. + // + void Empty(); + + // Copies the data, and then preprocesses it to make sure + // it's all valid. If it's not valid, returns false. + // + bool Initialize(std::string_view data); + + // Compare two types. If they aren't equal, log an error and return false. + // + static bool CheckType(ELxLuaValueType Type, ELxLuaValueType Desired); + +public: + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + int Length() const { return Types.Num(); } + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + int GetCursor() const { return Cursor; } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + void SetCursor(int n) { Cursor = n; } + +private: + // + // Functions that get values from the array, random access. + // + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + ELxLuaValueType GetType(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + bool IsType(int n, ELxLuaValueType Type) const { return GetType(n) == Type; } + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + FString GetString(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + FName GetName(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + double GetFloat(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + int GetInt(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + FVector GetVector(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + FVector2D GetVector2D(int n) const; + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + bool GetBoolean(int n) const; + + // + // Functions that get values from the array using the cursor. + // + +public: + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + ELxLuaValueType NextType() const { return GetType(Cursor); } + + UFUNCTION(BlueprintPure, Category = "Luprex|Lua Value Array") + bool IsNextType(ELxLuaValueType Type) const { return IsType(Cursor, Type); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + FString ReadString() { return GetString(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + FName ReadName() { return GetName(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + double ReadFloat() { return GetFloat(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + int ReadInt() { return GetInt(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + FVector ReadVector() { return GetVector(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + FVector2D ReadVector2D() { return GetVector2D(Cursor++); } + + UFUNCTION(BlueprintCallable, Category = "Luprex|Lua Value Array") + bool ReadBoolean() { return GetBoolean(Cursor++); } +}; \ No newline at end of file diff --git a/Source/Integration/Tangible.cpp b/Source/Integration/Tangible.cpp index 5b721a0b..67a0b014 100644 --- a/Source/Integration/Tangible.cpp +++ b/Source/Integration/Tangible.cpp @@ -6,7 +6,6 @@ #include "LuprexGameModeBase.h" #define DEFAULT_BLUEPRINT (TEXT("TangibleStaticMesh")) -#define LOCTEXT_NAMESPACE "Luprex Tangible" UlxTangible::UlxTangible() { diff --git a/Source/Integration/TangibleManager.cpp b/Source/Integration/TangibleManager.cpp index d65a3d90..137ba8cb 100644 --- a/Source/Integration/TangibleManager.cpp +++ b/Source/Integration/TangibleManager.cpp @@ -7,8 +7,6 @@ #include "LuprexGameModeBase.h" using namespace DebugPrint; -using TanArray = UlxTangibleManager::TanArray; -using IdArray = UlxTangibleManager::IdArray; UFunction *UlxTangibleManager::GetAnimationQueueChanged(UClass *uclass) { UFunction *result = uclass->FindFunctionByName(FName(TEXT("Animation Queue Changed"))); @@ -82,7 +80,7 @@ void UlxTangibleManager::DeleteTangible(int64 id) { // IMPLEMENT ME } -TanArray UlxTangibleManager::GetAllTangibles() const { +UlxTangibleManager::TanArray UlxTangibleManager::GetAllTangibles() const { TanArray result; result.SetNum(IdToTangible.Num()); int next = 0; @@ -141,7 +139,7 @@ void UlxTangibleManager::DeleteFarawayTangibles() { } } -IdArray UlxTangibleManager::GetIds(const TanArray &arr) { +UlxTangibleManager::IdArray UlxTangibleManager::GetIds(const TanArray &arr) { IdArray result; result.SetNum(arr.Num()); for (int i = 0; i < arr.Num(); i++) { diff --git a/Source/Integration/TriggeredTask.h b/Source/Integration/TriggeredTask.h index d84aee66..5e781a4f 100644 --- a/Source/Integration/TriggeredTask.h +++ b/Source/Integration/TriggeredTask.h @@ -1,3 +1,4 @@ +#pragma once #include "CoreMinimal.h"