Code cleanup and refactoring.

This commit is contained in:
2026-02-09 13:54:00 -05:00
parent 56765fdc16
commit db35967fb9
23 changed files with 271 additions and 275 deletions

View File

@@ -47,7 +47,15 @@
"--header-insertion=never" "--header-insertion=never"
], ],
"C_Cpp.autocomplete": "disabled", "C_Cpp.autocomplete": "disabled",
"search.useIgnoreFiles": true "search.useIgnoreFiles": true,
"search.exclude": {
"**/Intermediate": true,
"**/Saved": true,
"**/Binaries": true,
"**/DerivedDataCache": true,
"**/*.generated.h": true,
"**/*.gen.cpp": true
}
}, },
"extensions": { "extensions": {
"recommendations": [ "recommendations": [

View File

@@ -1,4 +1,5 @@
#include "Common.h"
#include "AnimQueue.h" #include "AnimQueue.h"
#include "UtilityLibrary.h" #include "UtilityLibrary.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
@@ -6,7 +7,6 @@
#include "Components/StaticMeshComponent.h" #include "Components/StaticMeshComponent.h"
#include "Components/SkeletalMeshComponent.h" #include "Components/SkeletalMeshComponent.h"
#include "AssetLookup.h" #include "AssetLookup.h"
#include "LuprexGameModeBase.h"
#include "Materials/MaterialInstanceDynamic.h" #include "Materials/MaterialInstanceDynamic.h"
#include <iostream> #include <iostream>
@@ -42,35 +42,35 @@ static bool SetProperty(const FString& prefix, UObject* obj, const FlxAnimationF
FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data()); FString sname(field.Name.size(), (const UTF8CHAR*)field.Name.data());
FName nname(prefix + sname); FName nname(prefix + sname);
switch (field.Type) { switch (field.Type) {
case SimpleDynamicTag::STRING: { case LuaValueType::STRING: {
FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname); FStrProperty* fprop = FindFProperty<FStrProperty>(uclass, nname);
if (fprop == nullptr) return false; if (fprop == nullptr) return false;
FString* pptr = fprop->ContainerPtrToValuePtr<FString>(obj); FString* pptr = fprop->ContainerPtrToValuePtr<FString>(obj);
*pptr = FString(field.S.size(), (const UTF8CHAR*)field.S.data()); *pptr = FString(field.S.size(), (const UTF8CHAR*)field.S.data());
return true; return true;
} }
case SimpleDynamicTag::TOKEN: { case LuaValueType::TOKEN: {
FNameProperty* fprop = FindFProperty<FNameProperty>(uclass, nname); FNameProperty* fprop = FindFProperty<FNameProperty>(uclass, nname);
if (fprop == nullptr) return false; if (fprop == nullptr) return false;
FName* pptr = fprop->ContainerPtrToValuePtr<FName>(obj); FName* pptr = fprop->ContainerPtrToValuePtr<FName>(obj);
*pptr = FName(field.S.size(), (const UTF8CHAR*)field.S.data(), FNAME_Add); *pptr = FName(field.S.size(), (const UTF8CHAR*)field.S.data(), FNAME_Add);
return true; return true;
} }
case SimpleDynamicTag::NUMBER: { case LuaValueType::NUMBER: {
FDoubleProperty* fprop = FindFProperty<FDoubleProperty>(uclass, nname); FDoubleProperty* fprop = FindFProperty<FDoubleProperty>(uclass, nname);
if (fprop == nullptr) return false; if (fprop == nullptr) return false;
double* pptr = fprop->ContainerPtrToValuePtr<double>(obj); double* pptr = fprop->ContainerPtrToValuePtr<double>(obj);
*pptr = field.X; *pptr = field.X;
return true; return true;
} }
case SimpleDynamicTag::BOOLEAN: { case LuaValueType::BOOLEAN: {
FBoolProperty* fprop = FindFProperty<FBoolProperty>(uclass, nname); FBoolProperty* fprop = FindFProperty<FBoolProperty>(uclass, nname);
if (fprop == nullptr) return false; if (fprop == nullptr) return false;
uint8* pptr = fprop->ContainerPtrToValuePtr<uint8>(obj); uint8* pptr = fprop->ContainerPtrToValuePtr<uint8>(obj);
fprop->SetPropertyValue(pptr, (field.X == 1.0)); fprop->SetPropertyValue(pptr, (field.X == 1.0));
return true; return true;
} }
case SimpleDynamicTag::VECTOR: { case LuaValueType::VECTOR: {
FStructProperty* fprop = FindFProperty<FStructProperty>(uclass, nname); FStructProperty* fprop = FindFProperty<FStructProperty>(uclass, nname);
if (fprop == nullptr) return false; if (fprop == nullptr) return false;
if (fprop->Struct != TBaseStructure<FVector>::Get()) return false; if (fprop->Struct != TBaseStructure<FVector>::Get()) return false;
@@ -128,14 +128,14 @@ void UlxAnimationStepLibrary::UnpackAnimationStep(bool &bChanged, FString &Actio
FlxAnimationField actionfield; FlxAnimationField actionfield;
actionfield.Name = "action"; actionfield.Name = "action";
actionfield.Persistent = false; actionfield.Persistent = false;
actionfield.Type = SimpleDynamicTag::STRING; actionfield.Type = LuaValueType::STRING;
actionfield.S = "unknown"; actionfield.S = "unknown";
// Decode everything. If an action field is found, save it for later. // Decode everything. If an action field is found, save it for later.
ClearProperties(prefix, target, stepproperty); ClearProperties(prefix, target, stepproperty);
while (!decoder.AtEOF()) { while (!decoder.AtEOF()) {
FlxAnimationField field = decoder.ReadField(); FlxAnimationField field = decoder.ReadField();
if ((field.Type == SimpleDynamicTag::STRING) && (field.Name == "action")) { if ((field.Type == LuaValueType::STRING) && (field.Name == "action")) {
actionfield.S = field.S; actionfield.S = field.S;
continue; continue;
} }
@@ -174,7 +174,7 @@ static FlxAnimationField FindAnimationFieldLL(const FlxAnimationStep& step, std:
return result; return result;
} }
} }
result.Type = SimpleDynamicTag::UNINITIALIZED; result.Type = LuaValueType::UNINITIALIZED;
return result; return result;
} }
@@ -186,21 +186,21 @@ static FlxAnimationField FindAnimationField(const FlxAnimationStep& step, const
void FlxAnimationStep::AutoUpdateXYZ(AActor *actor) const { void FlxAnimationStep::AutoUpdateXYZ(AActor *actor) const {
FlxAnimationField xyz = FindAnimationFieldLL(*this, "xyz"); FlxAnimationField xyz = FindAnimationFieldLL(*this, "xyz");
if (xyz.Type == SimpleDynamicTag::VECTOR) { if (xyz.Type == LuaValueType::VECTOR) {
actor->SetActorLocation(FVector(xyz.X, xyz.Y, xyz.Z)); actor->SetActorLocation(FVector(xyz.X, xyz.Y, xyz.Z));
} }
} }
void FlxAnimationStep::AutoUpdateFacing(AActor *actor) const { void FlxAnimationStep::AutoUpdateFacing(AActor *actor) const {
FlxAnimationField facing = FindAnimationFieldLL(*this, "facing"); FlxAnimationField facing = FindAnimationFieldLL(*this, "facing");
if (facing.Type == SimpleDynamicTag::NUMBER) { if (facing.Type == LuaValueType::NUMBER) {
actor->SetActorRotation(FRotator(0, facing.X, 0)); actor->SetActorRotation(FRotator(0, facing.X, 0));
} }
} }
void FlxAnimationStep::AutoUpdatePlane(FName *planep) const { void FlxAnimationStep::AutoUpdatePlane(FName *planep) const {
FlxAnimationField plane = FindAnimationFieldLL(*this, "plane"); FlxAnimationField plane = FindAnimationFieldLL(*this, "plane");
if (plane.Type == SimpleDynamicTag::STRING) { if (plane.Type == LuaValueType::STRING) {
FString pname(plane.S.size(), (const UTF8CHAR*)(plane.S.data())); FString pname(plane.S.size(), (const UTF8CHAR*)(plane.S.data()));
*planep = FName(pname); *planep = FName(pname);
} }
@@ -216,13 +216,13 @@ bool UlxAnimationStepLibrary::AnimationStepIsIdle(const FlxAnimationStep &step)
FVector UlxAnimationStepLibrary::AnimationStepGetVector(const FlxAnimationStep& step, const FString& name) { FVector UlxAnimationStepLibrary::AnimationStepGetVector(const FlxAnimationStep& step, const FString& name) {
FlxAnimationField field = FindAnimationField(step, name); FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != SimpleDynamicTag::VECTOR) return FVector(0, 0, 0); if (field.Type != LuaValueType::VECTOR) return FVector(0, 0, 0);
return FVector(field.X, field.Y, field.Z); return FVector(field.X, field.Y, field.Z);
} }
double UlxAnimationStepLibrary::AnimationStepGetFloat(const FlxAnimationStep& step, const FString& name) { double UlxAnimationStepLibrary::AnimationStepGetFloat(const FlxAnimationStep& step, const FString& name) {
FlxAnimationField field = FindAnimationField(step, name); FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != SimpleDynamicTag::NUMBER) return 0.0; if (field.Type != LuaValueType::NUMBER) return 0.0;
return field.X; return field.X;
} }
@@ -231,19 +231,19 @@ FString UlxAnimationStepLibrary::AnimationStepGetString(const FlxAnimationStep&
return TEXT("idle"); return TEXT("idle");
} }
FlxAnimationField field = FindAnimationField(step, name); FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != SimpleDynamicTag::STRING) return TEXT(""); if (field.Type != LuaValueType::STRING) return TEXT("");
return FString(field.S.size(), (const UTF8CHAR*)(field.S.data())); return FString(field.S.size(), (const UTF8CHAR*)(field.S.data()));
} }
FName UlxAnimationStepLibrary::AnimationStepGetName(const FlxAnimationStep& step, const FString& name) { FName UlxAnimationStepLibrary::AnimationStepGetName(const FlxAnimationStep& step, const FString& name) {
FlxAnimationField field = FindAnimationField(step, name); FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != SimpleDynamicTag::TOKEN) return FName(); if (field.Type != LuaValueType::TOKEN) return FName();
return FName(field.S.size(), (const UTF8CHAR*)(field.S.data()), FNAME_Add); return FName(field.S.size(), (const UTF8CHAR*)(field.S.data()), FNAME_Add);
} }
bool UlxAnimationStepLibrary::AnimationStepGetBool(const FlxAnimationStep& step, const FString& name) { bool UlxAnimationStepLibrary::AnimationStepGetBool(const FlxAnimationStep& step, const FString& name) {
FlxAnimationField field = FindAnimationField(step, name); FlxAnimationField field = FindAnimationField(step, name);
if (field.Type != SimpleDynamicTag::BOOLEAN) return false; if (field.Type != LuaValueType::BOOLEAN) return false;
return field.X == 1.0; return field.X == 1.0;
} }
@@ -252,25 +252,25 @@ FlxAnimationField FlxAnimationStepDecoder::ReadField() {
FlxAnimationField result; FlxAnimationField result;
result.Name = Decoder.read_string_view(); result.Name = Decoder.read_string_view();
result.Persistent = Decoder.read_bool(); result.Persistent = Decoder.read_bool();
result.Type = (SimpleDynamicTag)Decoder.read_uint8(); result.Type = (LuaValueType)Decoder.read_uint8();
switch (result.Type) { switch (result.Type) {
case SimpleDynamicTag::STRING: { case LuaValueType::STRING: {
result.S = Decoder.read_string_view(); result.S = Decoder.read_string_view();
break; break;
} }
case SimpleDynamicTag::TOKEN: { case LuaValueType::TOKEN: {
result.S = Decoder.read_string_view(); result.S = Decoder.read_string_view();
break; break;
} }
case SimpleDynamicTag::NUMBER: { case LuaValueType::NUMBER: {
result.X = Decoder.read_double(); result.X = Decoder.read_double();
break; break;
} }
case SimpleDynamicTag::BOOLEAN: { case LuaValueType::BOOLEAN: {
result.X = Decoder.read_bool() ? 1.0 : 0.0; result.X = Decoder.read_bool() ? 1.0 : 0.0;
break; break;
} }
case SimpleDynamicTag::VECTOR: { case LuaValueType::VECTOR: {
result.X = Decoder.read_double(); result.X = Decoder.read_double();
result.Y = Decoder.read_double(); result.Y = Decoder.read_double();
result.Z = Decoder.read_double(); result.Z = Decoder.read_double();
@@ -278,7 +278,7 @@ FlxAnimationField FlxAnimationStepDecoder::ReadField() {
} }
default: { default: {
Decoder.read_bytes(Decoder.fill()); Decoder.read_bytes(Decoder.fill());
result.Type = SimpleDynamicTag::UNINITIALIZED; result.Type = LuaValueType::UNINITIALIZED;
break; break;
} }
} }
@@ -298,19 +298,19 @@ FString FlxAnimationStepDecoder::DebugString(bool finished, int64 hash, std::str
result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data())); result.Append(FString(field.Name.size(), (const UTF8CHAR*)field.Name.data()));
result.Append(field.Persistent ? TEXT("=") : TEXT(":")); result.Append(field.Persistent ? TEXT("=") : TEXT(":"));
switch (field.Type) { switch (field.Type) {
case SimpleDynamicTag::STRING: case LuaValueType::STRING:
result.Append(FString(field.S.size(), (const UTF8CHAR*)field.S.data())); result.Append(FString(field.S.size(), (const UTF8CHAR*)field.S.data()));
break; break;
case SimpleDynamicTag::TOKEN: case LuaValueType::TOKEN:
result.Appendf(TEXT("[%s]"), *FString(field.S.size(), (const UTF8CHAR*)field.S.data())); result.Appendf(TEXT("[%s]"), *FString(field.S.size(), (const UTF8CHAR*)field.S.data()));
break; break;
case SimpleDynamicTag::NUMBER: case LuaValueType::NUMBER:
result.Appendf(TEXT("%lf"), field.X); result.Appendf(TEXT("%lf"), field.X);
break; break;
case SimpleDynamicTag::BOOLEAN: case LuaValueType::BOOLEAN:
result.Append((field.X) == 1.0 ? TEXT("true") : TEXT("false")); result.Append((field.X) == 1.0 ? TEXT("true") : TEXT("false"));
break; break;
case SimpleDynamicTag::VECTOR: case LuaValueType::VECTOR:
result.Appendf(TEXT("%lf,%lf,%lf"), field.X, field.Y, field.Z); result.Appendf(TEXT("%lf,%lf,%lf"), field.X, field.Y, field.Z);
break; break;
} }
@@ -557,9 +557,9 @@ void UlxAnimationStepLibrary::AnimationStepApplyMaterials(const FlxAnimationStep
if (field.Name.substr(0, 4) != "mat_") continue; if (field.Name.substr(0, 4) != "mat_") continue;
std::string_view suffix = field.Name.substr(4); std::string_view suffix = field.Name.substr(4);
FName paramName(suffix.size(), (const UTF8CHAR*)suffix.data()); FName paramName(suffix.size(), (const UTF8CHAR*)suffix.data());
if (field.Type == SimpleDynamicTag::VECTOR) { if (field.Type == LuaValueType::VECTOR) {
VectorParams.Add(paramName, FVector(field.X, field.Y, field.Z)); VectorParams.Add(paramName, FVector(field.X, field.Y, field.Z));
} else if (field.Type == SimpleDynamicTag::NUMBER) { } else if (field.Type == LuaValueType::NUMBER) {
ScalarParams.Add(paramName, (float)field.X); ScalarParams.Add(paramName, (float)field.X);
} }
} }
@@ -658,13 +658,12 @@ void UlxAnimationStepLibrary::AnimationStepApplyMesh(const FlxAnimationStep& ste
StaticComp->SetStaticMesh(NewMesh); StaticComp->SetStaticMesh(NewMesh);
} }
} else if (USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(MeshComp)) { } else if (USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(MeshComp)) {
// TODO: Skeletal mesh support USkeletalMesh* NewMesh = nullptr;
// USkeletalMesh* NewMesh = nullptr; UlxAssetLookup::LoadSkeletalMeshAsset(NewMesh, actor, MeshName, true);
// UlxAssetLookup::LoadSkeletalMeshAsset(NewMesh, actor, MeshName, true); if (NewMesh == nullptr) return;
// if (NewMesh == nullptr) return; if (SkelComp->GetSkeletalMeshAsset() != NewMesh) {
// if (SkelComp->GetSkeletalMeshAsset() != NewMesh) { SkelComp->SetSkeletalMeshAsset(NewMesh);
// SkelComp->SetSkeletalMeshAsset(NewMesh); }
// }
} else { } else {
UE_LOG(LogLuprexIntegration, Error, TEXT("AnimationStepApplyMesh: Actor %s has unsupported mesh component type"), *actor->GetName()); UE_LOG(LogLuprexIntegration, Error, TEXT("AnimationStepApplyMesh: Actor %s has unsupported mesh component type"), *actor->GetName());
} }

View File

@@ -172,7 +172,7 @@ struct FlxAnimationStepView {
struct FlxAnimationField { struct FlxAnimationField {
std::string_view Name; std::string_view Name;
bool Persistent; bool Persistent;
SimpleDynamicTag Type; LuaValueType Type;
double X, Y, Z; double X, Y, Z;
std::string_view S; std::string_view S;
}; };

View File

@@ -9,6 +9,7 @@
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Animation/AnimSequence.h" #include "Animation/AnimSequence.h"
#include "Engine/StaticMesh.h" #include "Engine/StaticMesh.h"
#include "Engine/SkeletalMesh.h"
const ElxValidOrNotValid NotValid = ElxValidOrNotValid::NotValid; const ElxValidOrNotValid NotValid = ElxValidOrNotValid::NotValid;
@@ -19,6 +20,7 @@ void UlxAssetLookup::RebuildIndex()
IAssetRegistry::GetChecked().WaitForCompletion(); IAssetRegistry::GetChecked().WaitForCompletion();
AssetPaths.Empty(); AssetPaths.Empty();
AddAssets(TEXT("/Game/StaticMeshes"), UStaticMesh::StaticClass(), TEXT("SM_")); AddAssets(TEXT("/Game/StaticMeshes"), UStaticMesh::StaticClass(), TEXT("SM_"));
AddAssets(TEXT("/Game/SkeletalMeshes"), USkeletalMesh::StaticClass(), TEXT("SK_"));
AddAssets(TEXT("/Game/AnimSequences"), UAnimSequence::StaticClass(), TEXT("SEQ_")); AddAssets(TEXT("/Game/AnimSequences"), UAnimSequence::StaticClass(), TEXT("SEQ_"));
AddAssets(TEXT("/Game/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_")); AddAssets(TEXT("/Game/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_"));
AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_")); AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_"));
@@ -99,6 +101,13 @@ ElxValidOrNotValid UlxAssetLookup::LoadStaticMeshAsset(
return Result ? Valid : NotValid; return Result ? Valid : NotValid;
} }
ElxValidOrNotValid UlxAssetLookup::LoadSkeletalMeshAsset(
USkeletalMesh *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
{
Result = (USkeletalMesh *)LoadAsset(Context, USkeletalMesh::StaticClass(), nullptr, Name, ErrorIfNotFound);
return Result ? Valid : NotValid;
}
ElxValidOrNotValid UlxAssetLookup::LoadAnimSequenceAsset( ElxValidOrNotValid UlxAssetLookup::LoadAnimSequenceAsset(
UAnimSequence *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound) UAnimSequence *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
{ {

View File

@@ -3,7 +3,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "UObject/NoExportTypes.h" #include "UObject/NoExportTypes.h"
#include "CommonTypes.h" #include "Common.h"
#include "Templates/Tuple.h" #include "Templates/Tuple.h"
#include "AssetLookup.generated.h" #include "AssetLookup.generated.h"
@@ -11,6 +11,7 @@ class AActor;
class UUserWidget; class UUserWidget;
class UlxLookAtWidget; class UlxLookAtWidget;
class UStaticMesh; class UStaticMesh;
class USkeletalMesh;
class UAnimSequence; class UAnimSequence;
UCLASS(MinimalAPI) UCLASS(MinimalAPI)
@@ -44,6 +45,12 @@ public:
UStaticMesh *&Result, UStaticMesh *&Result,
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false); const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
// Get a skeletal mesh by name
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
static ElxValidOrNotValid LoadSkeletalMeshAsset(
USkeletalMesh *&Result,
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
// Get an animation sequence by name. // Get an animation sequence by name.
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading") UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
static ElxValidOrNotValid LoadAnimSequenceAsset( static ElxValidOrNotValid LoadAnimSequenceAsset(

View File

@@ -0,0 +1,4 @@
#include "Common.h"
DEFINE_LOG_CATEGORY(LogLuprex);
DEFINE_LOG_CATEGORY(LogLuprexIntegration);

View File

@@ -0,0 +1,96 @@
#pragma once
#include <string_view>
#include "Common.generated.h"
/////////////////////////////////////////////////////////////////
//
// A bunch of simple data types that are used throughout the
// unreal interface to Luprex.
//
/////////////////////////////////////////////////////////////////
namespace LpxCommonTypes {
// Array of tangible IDs.
using IdArray = TArray<int64>;
// View of Array of tangible IDs.
using IdView = TArrayView<const int64>;
// Array of std::string_view
using StringViewVec = TArray<std::string_view>;
}
/////////////////////////////////////////////////////////////////
//
// Luprex exports a header-only library called "base-buffer.hpp",
// which includes a "struct LuaValueHolder" which contains a tag
// field of type "enum LuaValueType." The following enum is a
// direct copy of that enum, and the values must match one-for-one.
// Note that "token" has been renamed to "name", those are
// synonymous.
//
/////////////////////////////////////////////////////////////////
UENUM(BlueprintType)
enum class ElxLuaValueType : uint8 {
End,
String,
Name,
Float,
Boolean,
Vector
};
/////////////////////////////////////////////////////////////////
//
// A variety of boolean-like results that can be conveniently
// be used in conjunction with 'ExpandEnumAsExecs' to create
// branching functions.
//
/////////////////////////////////////////////////////////////////
UENUM(BlueprintType)
enum class ElxSuccessOrError : uint8 {
Success,
Error,
};
UENUM(BlueprintType)
enum class ElxValidOrNotValid : uint8 {
Valid,
NotValid,
};
UENUM(BlueprintType)
enum class ElxFoundOrNotFound : uint8 {
Found,
NotFound,
};
UENUM(BlueprintType)
enum class ElxUsedOrNotUsed : uint8 {
Used,
NotUsed,
};
UENUM(BlueprintType)
enum class ElxSuccessOrWrongType : uint8 {
Success,
WrongType,
};
/////////////////////////////////////////////////////////////////
//
// Two log categories that are used throughout the Unreal
// Luprex integration.
//
/////////////////////////////////////////////////////////////////
// Messages that come from inside the Luprex Core.
DECLARE_LOG_CATEGORY_EXTERN(LogLuprex, Display, All);
// Messages that pertain to our Luprex integration with Unreal.
DECLARE_LOG_CATEGORY_EXTERN(LogLuprexIntegration, Display, All);

View File

@@ -1,66 +0,0 @@
#pragma once
#include <string_view>
#include "CommonTypes.generated.h"
namespace CommonTypes {
// Array of tangible IDs.
using IdArray = TArray<int64>;
// View of Array of tangible IDs.
using IdView = TArrayView<const int64>;
// Array of std::string_view
using StringViewVec = TArray<std::string_view>;
}
UENUM(BlueprintType)
enum class ElxLuaValueType : uint8 {
End,
String,
Name,
Float,
Boolean,
Vector
};
/////////////////////////////////////////////////////////////////
//
// A variety of boolean-like results that can be conveniently
// be used in conjunction with 'ExpandEnumAsExecs' to create
// branching functions.
//
/////////////////////////////////////////////////////////////////
UENUM(BlueprintType)
enum class ElxSuccessOrError : uint8 {
Success,
Error,
};
UENUM(BlueprintType)
enum class ElxValidOrNotValid : uint8 {
Valid,
NotValid,
};
UENUM(BlueprintType)
enum class ElxFoundOrNotFound : uint8 {
Found,
NotFound,
};
UENUM(BlueprintType)
enum class ElxUsedOrNotUsed : uint8 {
Used,
NotUsed,
};
UENUM(BlueprintType)
enum class ElxSuccessOrWrongType : uint8 {
Success,
WrongType,
};

View File

@@ -1,52 +0,0 @@
#pragma once
//////////////////////////////////////////////////////////////
//
// ConsoleOutput
//
// This class stores the text that's in the unreal console.
// It stores it as one great big string, which contains
// newlines to denote line breaks.
//
// This class also contains a 'dirty' bit. Each time somebody
// appends a line of text to the console, the dirty bit is
// automatically set. The bit can be checked using 'IsDirty'
// and cleared using 'ClearDirty'. This makes it so that
// you don't have to update the unreal widget unless the
// text has actually changed.
//
//////////////////////////////////////////////////////////////
class FlxConsoleOutput {
private:
FString Content;
bool Dirty;
// Truncate the console to a reasonable number of
// lines. The length is hardwired.
void Truncate();
// Add a newline if there isn't one. Returns true if it changed anything.
bool MaybeAppendNewline();
// Append text. Returns true if it changed anything.
bool MaybeAppendText(const FString& text);
public:
// Append a line of text to the console.
void Append(const FString& text);
// Append a line of text to the console on a line by itself.
void AppendLine(const FString& text);
// Get the console text as a string.
const FString& Get() const { return Content; }
// Return if the dirty flag is set.
bool IsDirty() const { return Dirty; }
// Clear the dirty flag.
void ClearDirty() { Dirty = false; }
};

View File

@@ -4,7 +4,7 @@
#include "lpx-drvutil.hpp" #include "lpx-drvutil.hpp"
#include "lpx-paths.hpp" #include "lpx-paths.hpp"
using namespace CommonTypes; using namespace LpxCommonTypes;
void FlxLockedWrapper::DPrintHook(const char *Msg, size_t Size) void FlxLockedWrapper::DPrintHook(const char *Msg, size_t Size)

View File

@@ -2,7 +2,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "lpx-enginewrapper.hpp" #include "lpx-enginewrapper.hpp"
#include "CommonTypes.h" #include "Common.h"
// Class FlxLockableWrapper // Class FlxLockableWrapper
@@ -39,9 +39,9 @@ private:
public: public:
// Import these types into our Namespace. // Import these types into our Namespace.
using IdArray = CommonTypes::IdArray; using IdArray = LpxCommonTypes::IdArray;
using IdView = CommonTypes::IdView; using IdView = LpxCommonTypes::IdView;
using StringViewVec = CommonTypes::StringViewVec; using StringViewVec = LpxCommonTypes::StringViewVec;
public: public:

View File

@@ -294,7 +294,7 @@ void UlxLuaCallLibrary::LuaCallArgument_string(UObject *context, const FString &
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context); ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::STRING); sb.write_simple_dynamic_tag(LuaValueType::STRING);
sb.write_string(pstring); sb.write_string(pstring);
} }
@@ -309,7 +309,7 @@ void UlxLuaCallLibrary::LuaCallArgument_name(UObject *context, const FName &pnam
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context); ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::TOKEN); sb.write_simple_dynamic_tag(LuaValueType::TOKEN);
sb.write_string(namestr); sb.write_string(namestr);
} }
@@ -317,7 +317,7 @@ 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->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::NUMBER); sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
sb.write_double(pfloat); sb.write_double(pfloat);
} }
@@ -325,7 +325,7 @@ 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->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::NUMBER); sb.write_simple_dynamic_tag(LuaValueType::NUMBER);
sb.write_double(value); sb.write_double(value);
} }
@@ -333,7 +333,7 @@ void UlxLuaCallLibrary::LuaCallArgument_vector(UObject *context, const FVector &
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context); ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR); sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
sb.write_fvector(pvector); sb.write_fvector(pvector);
} }
@@ -341,7 +341,7 @@ void UlxLuaCallLibrary::LuaCallArgument_vector2d(UObject *context, const FVector
ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context); ALuprexGameModeBase *mode = ALuprexGameModeBase::FromContext(context);
FlxStreamBuffer &sb = mode->LuaCallGetBuffer(); FlxStreamBuffer &sb = mode->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR); sb.write_simple_dynamic_tag(LuaValueType::VECTOR);
sb.write_double(pvector.X); sb.write_double(pvector.X);
sb.write_double(pvector.Y); sb.write_double(pvector.Y);
sb.write_double(0.0); sb.write_double(0.0);
@@ -351,7 +351,7 @@ 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->LuaCallGetBuffer();
if (NotInitialized(sb)) return; if (NotInitialized(sb)) return;
sb.write_simple_dynamic_tag(SimpleDynamicTag::BOOLEAN); sb.write_simple_dynamic_tag(LuaValueType::BOOLEAN);
sb.write_bool(pbool); sb.write_bool(pbool);
} }
@@ -381,17 +381,17 @@ bool UlxLuaValues::Initialize(std::string_view data)
while (!Decoder.empty()) while (!Decoder.empty())
{ {
SimpleDynamicTag Tag = Decoder.read_simple_dynamic_tag(); LuaValueType Tag = Decoder.read_simple_dynamic_tag();
int64 Pos = Decoder.total_reads(); int64 Pos = Decoder.total_reads();
ElxLuaValueType Type; ElxLuaValueType Type;
switch (Tag) switch (Tag)
{ {
case SimpleDynamicTag::BOOLEAN: Type=ElxLuaValueType::Boolean; Decoder.read_bool(); break; case LuaValueType::BOOLEAN: Type=ElxLuaValueType::Boolean; Decoder.read_bool(); break;
case SimpleDynamicTag::NUMBER: Type=ElxLuaValueType::Float; Decoder.read_double(); break; case LuaValueType::NUMBER: Type=ElxLuaValueType::Float; Decoder.read_double(); break;
case SimpleDynamicTag::STRING: Type=ElxLuaValueType::String; Decoder.read_string_view(); break; case LuaValueType::STRING: Type=ElxLuaValueType::String; Decoder.read_string_view(); break;
case SimpleDynamicTag::TOKEN: Type=ElxLuaValueType::Name; Decoder.read_string_view(); break; case LuaValueType::TOKEN: Type=ElxLuaValueType::Name; Decoder.read_string_view(); break;
case SimpleDynamicTag::VECTOR: Type=ElxLuaValueType::Vector; Decoder.read_fvector(); break; case LuaValueType::VECTOR: Type=ElxLuaValueType::Vector; Decoder.read_fvector(); break;
default: { default: {
Empty(); Empty();
return false; return false;

View File

@@ -10,15 +10,12 @@
#include "Blueprint/WidgetBlueprintLibrary.h" #include "Blueprint/WidgetBlueprintLibrary.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "CommonTypes.h" #include "Common.h"
#include "AnimQueue.h" #include "AnimQueue.h"
#include <string> #include <string>
#include <string_view> #include <string_view>
using namespace CommonTypes; using namespace LpxCommonTypes;
DEFINE_LOG_CATEGORY(LogLuprex);
DEFINE_LOG_CATEGORY(LogLuprexIntegration);
ALuprexGameModeBase::ALuprexGameModeBase() ALuprexGameModeBase::ALuprexGameModeBase()
{ {

View File

@@ -16,15 +16,8 @@
#include "CommonActivatableWidget.h" #include "CommonActivatableWidget.h"
#include "LuprexGameModeBase.generated.h" #include "LuprexGameModeBase.generated.h"
// Messages that come from inside the Luprex Core.
DECLARE_LOG_CATEGORY_EXTERN(LogLuprex, Display, All);
// Messages that pertain to our Luprex integration with Unreal.
DECLARE_LOG_CATEGORY_EXTERN(LogLuprexIntegration, Display, All);
class UlxLuaValues; class UlxLuaValues;
UCLASS(BlueprintType) UCLASS(BlueprintType)
class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget
{ {
@@ -56,7 +49,7 @@ public:
// Initialize the Luprex DLL, and do other global initialization. // Initialize the Luprex DLL, and do other global initialization.
void InitializeGlobalState(); void InitializeGlobalState();
// Set the entire contents of the console output box. // Send prints into Unreal, for display on the virtual console.
UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Miscellaneous") UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Miscellaneous")
void ConsoleAddOutput(const FString& text); void ConsoleAddOutput(const FString& text);

View File

@@ -4,7 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h" #include "Kismet/BlueprintFunctionLibrary.h"
// #include "Kismet/KismetSystemLibrary.h" // #include "Kismet/KismetSystemLibrary.h"
// #include "CommonTypes.h" // #include "Common.h"
#include "ScriptedAnimation.generated.h" #include "ScriptedAnimation.generated.h"

View File

@@ -4,7 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "UObject/NoExportTypes.h" #include "UObject/NoExportTypes.h"
#include "CommonTypes.h" #include "Common.h"
#include "Tangible.h" #include "Tangible.h"
#include "TangibleManager.generated.h" #include "TangibleManager.generated.h"
@@ -17,8 +17,8 @@ class INTEGRATION_API UlxTangibleManager : public UObject
public: public:
// Types used frequently. // Types used frequently.
using IdView = CommonTypes::IdView; using IdView = LpxCommonTypes::IdView;
using IdArray = CommonTypes::IdArray; using IdArray = LpxCommonTypes::IdArray;
using TanArray = TArray<UlxTangible*>; using TanArray = TArray<UlxTangible*>;
// A pointer to our game mode. // A pointer to our game mode.

View File

@@ -5,7 +5,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Kismet/KismetSystemLibrary.h" #include "Kismet/KismetSystemLibrary.h"
#include "Input/Events.h" #include "Input/Events.h"
#include "CommonTypes.h" #include "Common.h"
#include "Kismet/BlueprintFunctionLibrary.h" #include "Kismet/BlueprintFunctionLibrary.h"
#include "UtilityLibrary.generated.h" #include "UtilityLibrary.generated.h"

View File

@@ -105,12 +105,12 @@ void AnimStepEditor::print_debug_string(eng::ostringstream &oss) {
oss << ":"; oss << ":";
} }
switch (value.type) { switch (value.type) {
case SimpleDynamicTag::UNINITIALIZED: oss << "UNINITIALIZED"; break; case LuaValueType::UNINITIALIZED: oss << "UNINITIALIZED"; break;
case SimpleDynamicTag::STRING: oss << value.s; break; case LuaValueType::STRING: oss << value.s; break;
case SimpleDynamicTag::TOKEN: oss << "[" << value.s << "]"; break; case LuaValueType::TOKEN: oss << "[" << value.s << "]"; break;
case SimpleDynamicTag::NUMBER: oss << value.x; break; case LuaValueType::NUMBER: oss << value.x; break;
case SimpleDynamicTag::BOOLEAN: oss << ((value.x == 1.0) ? "true":"false"); break; case LuaValueType::BOOLEAN: oss << ((value.x == 1.0) ? "true":"false"); break;
case SimpleDynamicTag::VECTOR: oss << value.x << "," << value.y << "," << value.z; break; case LuaValueType::VECTOR: oss << value.x << "," << value.y << "," << value.z; break;
default: assert(false); default: assert(false);
} }
first = false; first = false;
@@ -166,7 +166,7 @@ void AnimStepEditor::decode_persistent(std::string_view s) {
eng::string AnimStepEditor::add_default(const eng::string &name, const AnimValue &def, const AnimStepEditor *other) { eng::string AnimStepEditor::add_default(const eng::string &name, const AnimValue &def, const AnimStepEditor *other) {
AnimValue &value = map_[name]; AnimValue &value = map_[name];
value.persistent = true; value.persistent = true;
if (value.type == SimpleDynamicTag::UNINITIALIZED) { if (value.type == LuaValueType::UNINITIALIZED) {
if (other != nullptr) { if (other != nullptr) {
auto otheriter = other->map_.find(name); auto otheriter = other->map_.find(name);
if (otheriter != other->map_.end()) { if (otheriter != other->map_.end()) {
@@ -228,7 +228,7 @@ eng::string AnimStepEditor::from_lua(LuaCoreStack &LS0, LuaSlot tab, bool persis
return "in animation key-value pairs, key must be a valid lua identifier."; return "in animation key-value pairs, key must be a valid lua identifier.";
} }
AnimValue parsedvalue = parse_anim_value(LS, val); AnimValue parsedvalue = parse_anim_value(LS, val);
if (parsedvalue.type == SimpleDynamicTag::UNINITIALIZED) { if (parsedvalue.type == LuaValueType::UNINITIALIZED) {
return "in animation key-value pairs, value must be string, token, number, boolean, or xyz"; return "in animation key-value pairs, value must be string, token, number, boolean, or xyz";
} }
if (parsedvalue.is_token("auto") && !allowauto) { if (parsedvalue.is_token("auto") && !allowauto) {
@@ -253,15 +253,15 @@ eng::string AnimStepEditor::merge(const AnimStepEditor &previous, const AnimStep
// Handle autocalculation rules. // Handle autocalculation rules.
if (src.is_token("auto")) { if (src.is_token("auto")) {
if (name == "facing") { if (name == "facing") {
if (!dst.persistent || dst.type != SimpleDynamicTag::NUMBER) { if (!dst.persistent || dst.type != LuaValueType::NUMBER) {
return "Cannot auto-calculate facing because facing has not been specified as a persistent number"; return "Cannot auto-calculate facing because facing has not been specified as a persistent number";
} }
const auto xyz_previous = previous.map_.find("xyz"); const auto xyz_previous = previous.map_.find("xyz");
const auto xyz_update = update.map_.find("xyz"); const auto xyz_update = update.map_.find("xyz");
if ((xyz_previous == previous.map_.end()) || if ((xyz_previous == previous.map_.end()) ||
(xyz_update == update.map_.end()) || (xyz_update == update.map_.end()) ||
(xyz_previous->second.type != SimpleDynamicTag::VECTOR) || (xyz_previous->second.type != LuaValueType::VECTOR) ||
(xyz_update->second.type != SimpleDynamicTag::VECTOR)) { (xyz_update->second.type != LuaValueType::VECTOR)) {
return "Cannot auto-calculate facing because before/after xyz coordinates are not present"; return "Cannot auto-calculate facing because before/after xyz coordinates are not present";
} }
double dx = xyz_update->second.x - xyz_previous->second.x; double dx = xyz_update->second.x - xyz_previous->second.x;
@@ -298,15 +298,15 @@ void AnimStepEditor::to_lua(LuaCoreStack &LS0, LuaSlot tab, bool transient, bool
} }
LS.set(name, pair.first); LS.set(name, pair.first);
const AnimValue &value = pair.second; const AnimValue &value = pair.second;
if (value.type == SimpleDynamicTag::BOOLEAN) { if (value.type == LuaValueType::BOOLEAN) {
LS.set(val, (value.x == 1.0)); LS.set(val, (value.x == 1.0));
} else if (value.type == SimpleDynamicTag::NUMBER) { } else if (value.type == LuaValueType::NUMBER) {
LS.set(val, value.x); LS.set(val, value.x);
} else if (value.type == SimpleDynamicTag::STRING) { } else if (value.type == LuaValueType::STRING) {
LS.set(val, std::string_view(value.s)); LS.set(val, std::string_view(value.s));
} else if (value.type == SimpleDynamicTag::TOKEN) { } else if (value.type == LuaValueType::TOKEN) {
LS.set(val, LuaToken(value.s)); LS.set(val, LuaToken(value.s));
} else if (value.type == SimpleDynamicTag::VECTOR) { } else if (value.type == LuaValueType::VECTOR) {
LS.newtable(val); LS.newtable(val);
LS.rawset(val, 1, value.x); LS.rawset(val, 1, value.x);
LS.rawset(val, 2, value.y); LS.rawset(val, 2, value.y);
@@ -351,8 +351,8 @@ void AnimCoreState::decode(std::string_view s) {
bool persistent = sb.read_bool(); bool persistent = sb.read_bool();
sb.read_simple_dynamic(&value); sb.read_simple_dynamic(&value);
if (persistent) { if (persistent) {
if ((name == "xyz") && (value.type == SimpleDynamicTag::VECTOR)) xyz = util::DXYZ(value.x, value.y, value.z); if ((name == "xyz") && (value.type == LuaValueType::VECTOR)) xyz = util::DXYZ(value.x, value.y, value.z);
if ((name == "plane") && (value.type == SimpleDynamicTag::STRING)) plane = value.s; if ((name == "plane") && (value.type == LuaValueType::STRING)) plane = value.s;
} }
} }
} }

View File

@@ -124,23 +124,23 @@
#include <cassert> #include <cassert>
#include <ostream> #include <ostream>
struct AnimValue : public SimpleDynamicValue { struct AnimValue : public LuaValueHolderValue {
bool persistent; bool persistent;
AnimValue() { persistent = false; } AnimValue() { persistent = false; }
void set_token(LuaToken token) { void set_token(LuaToken token) {
type = SimpleDynamicTag::TOKEN; type = LuaValueType::TOKEN;
s=token.str(); x=y=z=0; s=token.str(); x=y=z=0;
} }
void set_dxyz(const util::DXYZ &xyz) { void set_dxyz(const util::DXYZ &xyz) {
type = SimpleDynamicTag::VECTOR; type = LuaValueType::VECTOR;
s.clear(); x = xyz.x; y = xyz.y; z = xyz.z; s.clear(); x = xyz.x; y = xyz.y; z = xyz.z;
} }
bool is_token(const char *t) const { bool is_token(const char *t) const {
return (type == SimpleDynamicTag::TOKEN) && (s == t); return (type == LuaValueType::TOKEN) && (s == t);
} }
}; };
@@ -226,7 +226,7 @@ public:
// //
// If 'allowauto' is true, then the lua table may contain a key-value // If 'allowauto' is true, then the lua table may contain a key-value
// pair of the form (key, math.auto). These keys will be stored in the // pair of the form (key, math.auto). These keys will be stored in the
// AnimStepEditor map with mapentry.type == SimpleDynamicTag::AUTO. // AnimStepEditor map with mapentry.type == LuaValueType::AUTO.
// This is done to express an intent that the value should be // This is done to express an intent that the value should be
// automatically computer later. // automatically computer later.
// //

View File

@@ -243,7 +243,7 @@ public:
virtual char const *what() const { return "Stream Corruption"; } virtual char const *what() const { return "Stream Corruption"; }
}; };
using SimpleDynamicValue = SimpleDynamic<eng::string>; using LuaValueHolderValue = LuaValueHolder<eng::string>;
class StreamBufferCore { class StreamBufferCore {
protected: protected:

View File

@@ -8,17 +8,17 @@
#include <iostream> #include <iostream>
// Read a SimpleDynamic value from the streambuffer and push // Read a LuaValueHolder value from the streambuffer and push
// it onto the lua stack. // it onto the lua stack.
void push_simple_dynamic(lua_State *L, StreamBuffer *sb) { void push_simple_dynamic(lua_State *L, StreamBuffer *sb) {
SimpleDynamicTag type = sb->read_simple_dynamic_tag(); LuaValueType type = sb->read_simple_dynamic_tag();
switch (type) { switch (type) {
case SimpleDynamicTag::STRING: { case LuaValueType::STRING: {
std::string_view s = sb->read_string_view(); std::string_view s = sb->read_string_view();
lua_pushlstring(L, s.data(), s.size()); lua_pushlstring(L, s.data(), s.size());
break; break;
} }
case SimpleDynamicTag::TOKEN: { case LuaValueType::TOKEN: {
std::string_view toktext = sb->read_string_view(); std::string_view toktext = sb->read_string_view();
LuaToken token(toktext); LuaToken token(toktext);
if (token.empty() && !toktext.empty()) { if (token.empty() && !toktext.empty()) {
@@ -27,15 +27,15 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) {
lua_pushlightuserdata(L, token.voidvalue()); lua_pushlightuserdata(L, token.voidvalue());
break; break;
} }
case SimpleDynamicTag::NUMBER: { case LuaValueType::NUMBER: {
lua_pushnumber(L, sb->read_double()); lua_pushnumber(L, sb->read_double());
break; break;
} }
case SimpleDynamicTag::BOOLEAN: { case LuaValueType::BOOLEAN: {
lua_pushboolean(L, sb->read_bool() ? 1:0); lua_pushboolean(L, sb->read_bool() ? 1:0);
break; break;
} }
case SimpleDynamicTag::VECTOR: { case LuaValueType::VECTOR: {
double x = sb->read_double(); double x = sb->read_double();
double y = sb->read_double(); double y = sb->read_double();
double z = sb->read_double(); double z = sb->read_double();
@@ -56,25 +56,25 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) {
bool encode_simple_dynamic(LuaCoreStack &LS, LuaSlot &slot, StreamBuffer *sb) { bool encode_simple_dynamic(LuaCoreStack &LS, LuaSlot &slot, StreamBuffer *sb) {
switch (LS.type(slot)) { switch (LS.type(slot)) {
case LUA_TSTRING: case LUA_TSTRING:
sb->write_simple_dynamic_tag(SimpleDynamicTag::STRING); sb->write_simple_dynamic_tag(LuaValueType::STRING);
sb->write_string(LS.ckstringview(slot)); sb->write_string(LS.ckstringview(slot));
return true; return true;
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA:
sb->write_simple_dynamic_tag(SimpleDynamicTag::TOKEN); sb->write_simple_dynamic_tag(LuaValueType::TOKEN);
sb->write_string(LS.cktoken(slot).str()); sb->write_string(LS.cktoken(slot).str());
return true; return true;
case LUA_TNUMBER: case LUA_TNUMBER:
sb->write_simple_dynamic_tag(SimpleDynamicTag::NUMBER); sb->write_simple_dynamic_tag(LuaValueType::NUMBER);
sb->write_double(LS.cknumber(slot)); sb->write_double(LS.cknumber(slot));
return true; return true;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
sb->write_simple_dynamic_tag(SimpleDynamicTag::BOOLEAN); sb->write_simple_dynamic_tag(LuaValueType::BOOLEAN);
sb->write_bool(LS.ckboolean(slot)); sb->write_bool(LS.ckboolean(slot));
return true; return true;
case LUA_TTABLE: { case LUA_TTABLE: {
std::optional<util::DXYZ> xyz = LS.tryxyz(slot); std::optional<util::DXYZ> xyz = LS.tryxyz(slot);
if (!xyz.has_value()) return false; if (!xyz.has_value()) return false;
sb->write_simple_dynamic_tag(SimpleDynamicTag::VECTOR); sb->write_simple_dynamic_tag(LuaValueType::VECTOR);
sb->write_dxyz(xyz.value()); sb->write_dxyz(xyz.value());
return true; return true;
} }
@@ -492,7 +492,7 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view
// return value of the function. // return value of the function.
// //
int64_t rv_base = retvals->total_writes(); int64_t rv_base = retvals->total_writes();
retvals->write_simple_dynamic_tag(SimpleDynamicTag::STRING); retvals->write_simple_dynamic_tag(LuaValueType::STRING);
retvals->write_string(msg); retvals->write_string(msg);
if (msg.empty()) { if (msg.empty()) {
@@ -521,7 +521,7 @@ void World::probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view
if (!ok) { if (!ok) {
msg = util::ss("Lua function ",classname,".",funcname," returned a non-serializable value"); msg = util::ss("Lua function ",classname,".",funcname," returned a non-serializable value");
retvals->unwrite_to(rv_base); retvals->unwrite_to(rv_base);
retvals->write_simple_dynamic_tag(SimpleDynamicTag::STRING); retvals->write_simple_dynamic_tag(LuaValueType::STRING);
retvals->write_string(msg); retvals->write_string(msg);
} }
} }

View File

@@ -17,21 +17,22 @@
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// //
// SimpleDynamic // LuaValueHolder
// //
// A struct that holds a dynamically typed value. // A struct that holds a dynamically typed value.
// This can hold a string, number, vector, or boolean. // This can hold a string, token, number, vector, or boolean.
// //
// The type is stored in the 'type' field. // The type is stored in the 'type' field.
// //
// If it's a STRING, the value is in the field s // If it's a STRING, the value is in the field s
// If it's a TOKEN, the value is stored in the field s
// If it's a NUMBER, the value is in the field x // If it's a NUMBER, the value is in the field x
// If it's a BOOLEAN, it's true if (x==1.0) // If it's a BOOLEAN, it's true if (x==1.0)
// If it's a VECTOR, the value is in x,y,z // If it's a VECTOR, the value is in x,y,z
// //
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
enum class SimpleDynamicTag { enum class LuaValueType {
UNINITIALIZED, UNINITIALIZED,
STRING, STRING,
TOKEN, TOKEN,
@@ -41,25 +42,25 @@ enum class SimpleDynamicTag {
}; };
template<class STRING> template<class STRING>
struct SimpleDynamic { struct LuaValueHolder {
using string = STRING; using string = STRING;
SimpleDynamicTag type; LuaValueType type;
double x, y, z; double x, y, z;
string s; string s;
SimpleDynamic() { LuaValueHolder() {
type = SimpleDynamicTag::UNINITIALIZED; type = LuaValueType::UNINITIALIZED;
x=y=z=0; x=y=z=0;
} }
static const char *type_name_of(SimpleDynamicTag t) { static const char *type_name_of(LuaValueType t) {
switch (t) { switch (t) {
case SimpleDynamicTag::UNINITIALIZED: return "uninitialized"; case LuaValueType::UNINITIALIZED: return "uninitialized";
case SimpleDynamicTag::STRING: return "string"; case LuaValueType::STRING: return "string";
case SimpleDynamicTag::TOKEN: return "token"; case LuaValueType::TOKEN: return "token";
case SimpleDynamicTag::BOOLEAN: return "boolean"; case LuaValueType::BOOLEAN: return "boolean";
case SimpleDynamicTag::NUMBER: return "number"; case LuaValueType::NUMBER: return "number";
case SimpleDynamicTag::VECTOR: return "vector"; case LuaValueType::VECTOR: return "vector";
default: return "unknown"; default: return "unknown";
} }
} }
@@ -69,30 +70,30 @@ struct SimpleDynamic {
} }
void set_uninitialized() { void set_uninitialized() {
type=SimpleDynamicTag::UNINITIALIZED; s.clear(); x=y=z=0; type=LuaValueType::UNINITIALIZED; s.clear(); x=y=z=0;
} }
void set_string(std::string_view is) { void set_string(std::string_view is) {
type=SimpleDynamicTag::STRING; s=is; x=y=z=0; type=LuaValueType::STRING; s=is; x=y=z=0;
} }
void set_token(std::string_view is) { void set_token(std::string_view is) {
type=SimpleDynamicTag::TOKEN; s=is; x=y=z=0; type=LuaValueType::TOKEN; s=is; x=y=z=0;
} }
void set_number(double n) { void set_number(double n) {
type = SimpleDynamicTag::NUMBER; s.clear(); x=n; y=z=0; type = LuaValueType::NUMBER; s.clear(); x=n; y=z=0;
} }
void set_boolean(bool b) { void set_boolean(bool b) {
type = SimpleDynamicTag::BOOLEAN; s.clear(); x=(b?1:0); y=z=0; type = LuaValueType::BOOLEAN; s.clear(); x=(b?1:0); y=z=0;
} }
void set_vector(double ix, double iy, double iz) { void set_vector(double ix, double iy, double iz) {
type = SimpleDynamicTag::VECTOR; s.clear(); x=ix; y=iy; z=iz; type = LuaValueType::VECTOR; s.clear(); x=ix; y=iy; z=iz;
} }
void copy_value(const SimpleDynamic &other) { void copy_value(const LuaValueHolder &other) {
type = other.type; type = other.type;
s=other.s; x=other.x; y=other.y; z=other.z; s=other.s; x=other.x; y=other.y; z=other.z;
} }
@@ -492,26 +493,26 @@ public:
write_bytes(s); write_bytes(s);
} }
// Write a SimpleDynamicTag. // Write a LuaValueType.
// //
void write_simple_dynamic_tag(SimpleDynamicTag tag) { void write_simple_dynamic_tag(LuaValueType tag) {
write_uint8(uint8_t(tag)); write_uint8(uint8_t(tag));
} }
// Write a SimpleDynamic value. // Write a LuaValueHolder value.
// //
// This works regardless of what kind of data is present in the // This works regardless of what kind of data is present in the
// SimpleDynamic. // LuaValueHolder.
// //
template<class STRING> template<class STRING>
void write_simple_dynamic(const SimpleDynamic<STRING> &sd) { void write_simple_dynamic(const LuaValueHolder<STRING> &sd) {
write_simple_dynamic_tag(sd.type); write_simple_dynamic_tag(sd.type);
switch(sd.type) { switch(sd.type) {
case SimpleDynamicTag::STRING: write_string(sd.s); break; case LuaValueType::STRING: write_string(sd.s); break;
case SimpleDynamicTag::TOKEN: write_string(sd.s); break; case LuaValueType::TOKEN: write_string(sd.s); break;
case SimpleDynamicTag::NUMBER: write_double(sd.x); break; case LuaValueType::NUMBER: write_double(sd.x); break;
case SimpleDynamicTag::BOOLEAN: write_bool(sd.x == 1.0); break; case LuaValueType::BOOLEAN: write_bool(sd.x == 1.0); break;
case SimpleDynamicTag::VECTOR: write_double(sd.x); write_double(sd.y); write_double(sd.z); break; case LuaValueType::VECTOR: write_double(sd.x); write_double(sd.y); write_double(sd.z); break;
default: assert(false); default: assert(false);
} }
} }
@@ -616,23 +617,23 @@ public:
return read_string_limit(0x1000000); return read_string_limit(0x1000000);
} }
// Read a SimpleDynamicTag // Read a LuaValueType
// //
SimpleDynamicTag read_simple_dynamic_tag() { LuaValueType read_simple_dynamic_tag() {
return SimpleDynamicTag(read_uint8()); return LuaValueType(read_uint8());
} }
// Read a SimpleDynamic // Read a LuaValueHolder
// //
template<class STRING> template<class STRING>
void read_simple_dynamic(SimpleDynamic<STRING> *result) { void read_simple_dynamic(LuaValueHolder<STRING> *result) {
SimpleDynamicTag type = read_simple_dynamic_tag(); LuaValueType type = read_simple_dynamic_tag();
switch (type) { switch (type) {
case SimpleDynamicTag::STRING: result->set_string(read_string()); break; case LuaValueType::STRING: result->set_string(read_string()); break;
case SimpleDynamicTag::TOKEN: result->set_token(read_string()); break; case LuaValueType::TOKEN: result->set_token(read_string()); break;
case SimpleDynamicTag::NUMBER: result->set_number(read_double()); break; case LuaValueType::NUMBER: result->set_number(read_double()); break;
case SimpleDynamicTag::BOOLEAN: result->set_boolean(read_bool()); break; case LuaValueType::BOOLEAN: result->set_boolean(read_bool()); break;
case SimpleDynamicTag::VECTOR: { case LuaValueType::VECTOR: {
double x=read_double(); double x=read_double();
double y=read_double(); double y=read_double();
double z=read_double(); double z=read_double();