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"
],
"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": {
"recommendations": [

View File

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

View File

@@ -9,6 +9,7 @@
#include "Blueprint/UserWidget.h"
#include "Animation/AnimSequence.h"
#include "Engine/StaticMesh.h"
#include "Engine/SkeletalMesh.h"
const ElxValidOrNotValid NotValid = ElxValidOrNotValid::NotValid;
@@ -19,6 +20,7 @@ void UlxAssetLookup::RebuildIndex()
IAssetRegistry::GetChecked().WaitForCompletion();
AssetPaths.Empty();
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/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_"));
AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_"));
@@ -99,6 +101,13 @@ ElxValidOrNotValid UlxAssetLookup::LoadStaticMeshAsset(
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(
UAnimSequence *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
{

View File

@@ -3,7 +3,7 @@
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "CommonTypes.h"
#include "Common.h"
#include "Templates/Tuple.h"
#include "AssetLookup.generated.h"
@@ -11,6 +11,7 @@ class AActor;
class UUserWidget;
class UlxLookAtWidget;
class UStaticMesh;
class USkeletalMesh;
class UAnimSequence;
UCLASS(MinimalAPI)
@@ -44,6 +45,12 @@ public:
UStaticMesh *&Result,
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.
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
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-paths.hpp"
using namespace CommonTypes;
using namespace LpxCommonTypes;
void FlxLockedWrapper::DPrintHook(const char *Msg, size_t Size)

View File

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

View File

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

View File

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

View File

@@ -16,15 +16,8 @@
#include "CommonActivatableWidget.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;
UCLASS(BlueprintType)
class INTEGRATION_API UlxLuaWidget : public UCommonActivatableWidget
{
@@ -56,7 +49,7 @@ public:
// Initialize the Luprex DLL, and do other global initialization.
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")
void ConsoleAddOutput(const FString& text);

View File

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

View File

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

View File

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

View File

@@ -105,12 +105,12 @@ void AnimStepEditor::print_debug_string(eng::ostringstream &oss) {
oss << ":";
}
switch (value.type) {
case SimpleDynamicTag::UNINITIALIZED: oss << "UNINITIALIZED"; break;
case SimpleDynamicTag::STRING: oss << value.s; break;
case SimpleDynamicTag::TOKEN: oss << "[" << value.s << "]"; break;
case SimpleDynamicTag::NUMBER: oss << value.x; break;
case SimpleDynamicTag::BOOLEAN: oss << ((value.x == 1.0) ? "true":"false"); break;
case SimpleDynamicTag::VECTOR: oss << value.x << "," << value.y << "," << value.z; break;
case LuaValueType::UNINITIALIZED: oss << "UNINITIALIZED"; break;
case LuaValueType::STRING: oss << value.s; break;
case LuaValueType::TOKEN: oss << "[" << value.s << "]"; break;
case LuaValueType::NUMBER: oss << value.x; break;
case LuaValueType::BOOLEAN: oss << ((value.x == 1.0) ? "true":"false"); break;
case LuaValueType::VECTOR: oss << value.x << "," << value.y << "," << value.z; break;
default: assert(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) {
AnimValue &value = map_[name];
value.persistent = true;
if (value.type == SimpleDynamicTag::UNINITIALIZED) {
if (value.type == LuaValueType::UNINITIALIZED) {
if (other != nullptr) {
auto otheriter = other->map_.find(name);
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.";
}
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";
}
if (parsedvalue.is_token("auto") && !allowauto) {
@@ -253,15 +253,15 @@ eng::string AnimStepEditor::merge(const AnimStepEditor &previous, const AnimStep
// Handle autocalculation rules.
if (src.is_token("auto")) {
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";
}
const auto xyz_previous = previous.map_.find("xyz");
const auto xyz_update = update.map_.find("xyz");
if ((xyz_previous == previous.map_.end()) ||
(xyz_update == update.map_.end()) ||
(xyz_previous->second.type != SimpleDynamicTag::VECTOR) ||
(xyz_update->second.type != SimpleDynamicTag::VECTOR)) {
(xyz_previous->second.type != LuaValueType::VECTOR) ||
(xyz_update->second.type != LuaValueType::VECTOR)) {
return "Cannot auto-calculate facing because before/after xyz coordinates are not present";
}
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);
const AnimValue &value = pair.second;
if (value.type == SimpleDynamicTag::BOOLEAN) {
if (value.type == LuaValueType::BOOLEAN) {
LS.set(val, (value.x == 1.0));
} else if (value.type == SimpleDynamicTag::NUMBER) {
} else if (value.type == LuaValueType::NUMBER) {
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));
} else if (value.type == SimpleDynamicTag::TOKEN) {
} else if (value.type == LuaValueType::TOKEN) {
LS.set(val, LuaToken(value.s));
} else if (value.type == SimpleDynamicTag::VECTOR) {
} else if (value.type == LuaValueType::VECTOR) {
LS.newtable(val);
LS.rawset(val, 1, value.x);
LS.rawset(val, 2, value.y);
@@ -351,8 +351,8 @@ void AnimCoreState::decode(std::string_view s) {
bool persistent = sb.read_bool();
sb.read_simple_dynamic(&value);
if (persistent) {
if ((name == "xyz") && (value.type == SimpleDynamicTag::VECTOR)) xyz = util::DXYZ(value.x, value.y, value.z);
if ((name == "plane") && (value.type == SimpleDynamicTag::STRING)) plane = value.s;
if ((name == "xyz") && (value.type == LuaValueType::VECTOR)) xyz = util::DXYZ(value.x, value.y, value.z);
if ((name == "plane") && (value.type == LuaValueType::STRING)) plane = value.s;
}
}
}

View File

@@ -124,23 +124,23 @@
#include <cassert>
#include <ostream>
struct AnimValue : public SimpleDynamicValue {
struct AnimValue : public LuaValueHolderValue {
bool persistent;
AnimValue() { persistent = false; }
void set_token(LuaToken token) {
type = SimpleDynamicTag::TOKEN;
type = LuaValueType::TOKEN;
s=token.str(); x=y=z=0;
}
void set_dxyz(const util::DXYZ &xyz) {
type = SimpleDynamicTag::VECTOR;
type = LuaValueType::VECTOR;
s.clear(); x = xyz.x; y = xyz.y; z = xyz.z;
}
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
// 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
// automatically computer later.
//

View File

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

View File

@@ -8,17 +8,17 @@
#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.
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) {
case SimpleDynamicTag::STRING: {
case LuaValueType::STRING: {
std::string_view s = sb->read_string_view();
lua_pushlstring(L, s.data(), s.size());
break;
}
case SimpleDynamicTag::TOKEN: {
case LuaValueType::TOKEN: {
std::string_view toktext = sb->read_string_view();
LuaToken token(toktext);
if (token.empty() && !toktext.empty()) {
@@ -27,15 +27,15 @@ void push_simple_dynamic(lua_State *L, StreamBuffer *sb) {
lua_pushlightuserdata(L, token.voidvalue());
break;
}
case SimpleDynamicTag::NUMBER: {
case LuaValueType::NUMBER: {
lua_pushnumber(L, sb->read_double());
break;
}
case SimpleDynamicTag::BOOLEAN: {
case LuaValueType::BOOLEAN: {
lua_pushboolean(L, sb->read_bool() ? 1:0);
break;
}
case SimpleDynamicTag::VECTOR: {
case LuaValueType::VECTOR: {
double x = sb->read_double();
double y = 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) {
switch (LS.type(slot)) {
case LUA_TSTRING:
sb->write_simple_dynamic_tag(SimpleDynamicTag::STRING);
sb->write_simple_dynamic_tag(LuaValueType::STRING);
sb->write_string(LS.ckstringview(slot));
return true;
case LUA_TLIGHTUSERDATA:
sb->write_simple_dynamic_tag(SimpleDynamicTag::TOKEN);
sb->write_simple_dynamic_tag(LuaValueType::TOKEN);
sb->write_string(LS.cktoken(slot).str());
return true;
case LUA_TNUMBER:
sb->write_simple_dynamic_tag(SimpleDynamicTag::NUMBER);
sb->write_simple_dynamic_tag(LuaValueType::NUMBER);
sb->write_double(LS.cknumber(slot));
return true;
case LUA_TBOOLEAN:
sb->write_simple_dynamic_tag(SimpleDynamicTag::BOOLEAN);
sb->write_simple_dynamic_tag(LuaValueType::BOOLEAN);
sb->write_bool(LS.ckboolean(slot));
return true;
case LUA_TTABLE: {
std::optional<util::DXYZ> xyz = LS.tryxyz(slot);
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());
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.
//
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);
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) {
msg = util::ss("Lua function ",classname,".",funcname," returned a non-serializable value");
retvals->unwrite_to(rv_base);
retvals->write_simple_dynamic_tag(SimpleDynamicTag::STRING);
retvals->write_simple_dynamic_tag(LuaValueType::STRING);
retvals->write_string(msg);
}
}

View File

@@ -17,21 +17,22 @@
///////////////////////////////////////////////////////////////
//
// SimpleDynamic
// LuaValueHolder
//
// 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.
//
// 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 BOOLEAN, it's true if (x==1.0)
// If it's a VECTOR, the value is in x,y,z
//
///////////////////////////////////////////////////////////////
enum class SimpleDynamicTag {
enum class LuaValueType {
UNINITIALIZED,
STRING,
TOKEN,
@@ -41,25 +42,25 @@ enum class SimpleDynamicTag {
};
template<class STRING>
struct SimpleDynamic {
struct LuaValueHolder {
using string = STRING;
SimpleDynamicTag type;
LuaValueType type;
double x, y, z;
string s;
SimpleDynamic() {
type = SimpleDynamicTag::UNINITIALIZED;
LuaValueHolder() {
type = LuaValueType::UNINITIALIZED;
x=y=z=0;
}
static const char *type_name_of(SimpleDynamicTag t) {
static const char *type_name_of(LuaValueType t) {
switch (t) {
case SimpleDynamicTag::UNINITIALIZED: return "uninitialized";
case SimpleDynamicTag::STRING: return "string";
case SimpleDynamicTag::TOKEN: return "token";
case SimpleDynamicTag::BOOLEAN: return "boolean";
case SimpleDynamicTag::NUMBER: return "number";
case SimpleDynamicTag::VECTOR: return "vector";
case LuaValueType::UNINITIALIZED: return "uninitialized";
case LuaValueType::STRING: return "string";
case LuaValueType::TOKEN: return "token";
case LuaValueType::BOOLEAN: return "boolean";
case LuaValueType::NUMBER: return "number";
case LuaValueType::VECTOR: return "vector";
default: return "unknown";
}
}
@@ -69,30 +70,30 @@ struct SimpleDynamic {
}
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) {
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) {
type=SimpleDynamicTag::TOKEN; s=is; x=y=z=0;
type=LuaValueType::TOKEN; s=is; x=y=z=0;
}
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) {
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) {
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;
s=other.s; x=other.x; y=other.y; z=other.z;
}
@@ -492,26 +493,26 @@ public:
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 a SimpleDynamic value.
// Write a LuaValueHolder value.
//
// This works regardless of what kind of data is present in the
// SimpleDynamic.
// LuaValueHolder.
//
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);
switch(sd.type) {
case SimpleDynamicTag::STRING: write_string(sd.s); break;
case SimpleDynamicTag::TOKEN: write_string(sd.s); break;
case SimpleDynamicTag::NUMBER: write_double(sd.x); break;
case SimpleDynamicTag::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::STRING: write_string(sd.s); break;
case LuaValueType::TOKEN: write_string(sd.s); break;
case LuaValueType::NUMBER: write_double(sd.x); break;
case LuaValueType::BOOLEAN: write_bool(sd.x == 1.0); break;
case LuaValueType::VECTOR: write_double(sd.x); write_double(sd.y); write_double(sd.z); break;
default: assert(false);
}
}
@@ -616,23 +617,23 @@ public:
return read_string_limit(0x1000000);
}
// Read a SimpleDynamicTag
// Read a LuaValueType
//
SimpleDynamicTag read_simple_dynamic_tag() {
return SimpleDynamicTag(read_uint8());
LuaValueType read_simple_dynamic_tag() {
return LuaValueType(read_uint8());
}
// Read a SimpleDynamic
// Read a LuaValueHolder
//
template<class STRING>
void read_simple_dynamic(SimpleDynamic<STRING> *result) {
SimpleDynamicTag type = read_simple_dynamic_tag();
void read_simple_dynamic(LuaValueHolder<STRING> *result) {
LuaValueType type = read_simple_dynamic_tag();
switch (type) {
case SimpleDynamicTag::STRING: result->set_string(read_string()); break;
case SimpleDynamicTag::TOKEN: result->set_token(read_string()); break;
case SimpleDynamicTag::NUMBER: result->set_number(read_double()); break;
case SimpleDynamicTag::BOOLEAN: result->set_boolean(read_bool()); break;
case SimpleDynamicTag::VECTOR: {
case LuaValueType::STRING: result->set_string(read_string()); break;
case LuaValueType::TOKEN: result->set_token(read_string()); break;
case LuaValueType::NUMBER: result->set_number(read_double()); break;
case LuaValueType::BOOLEAN: result->set_boolean(read_bool()); break;
case LuaValueType::VECTOR: {
double x=read_double();
double y=read_double();
double z=read_double();