From 68aca1ff13cb38e3b1e7b83a114e98532b82f5b1 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sun, 31 Dec 2023 21:02:19 -0800 Subject: [PATCH] Remove std library usage where possible - Deprecate & remove ILogger and string_format - Migrate function handlers to delegate definitions, per Unreal structures - Add [[maybe_unused]] to UnrealLogHandler to indicate the parameters may be unused - Update parameters to const reference where possible (function handlers, etc.) - Update map references to use Unreal's TMap, vector references to use Unreal's TArray - Implement State::ClearStack - Rename YarnFunction to TYarnFunction and migrate from std::function to TDelegate --- Source/YarnSpinner/Private/DialogueRunner.cpp | 128 ++++---- .../Private/Library/YarnFunctionLibrary.cpp | 2 +- .../Private/Library/YarnLibraryRegistry.cpp | 4 +- Source/YarnSpinner/Private/YarnSpinner.cpp | 10 +- .../Private/YarnSpinnerCore/Library.cpp | 281 ++++++++++-------- .../Private/YarnSpinnerCore/State.cpp | 53 ++-- .../YarnSpinnerCore/VirtualMachine.cpp | 260 ++++++++-------- Source/YarnSpinner/Private/YarnSubsystem.cpp | 27 +- Source/YarnSpinner/Public/DialogueRunner.h | 17 +- .../Public/YarnSpinnerCore/Common.h | 54 +--- .../Public/YarnSpinnerCore/Library.h | 41 ++- .../Public/YarnSpinnerCore/State.h | 29 +- .../Public/YarnSpinnerCore/VirtualMachine.h | 55 ++-- Source/YarnSpinner/Public/YarnSubsystem.h | 12 +- .../Private/YarnAssetFactory.cpp | 7 +- 15 files changed, 469 insertions(+), 511 deletions(-) diff --git a/Source/YarnSpinner/Private/DialogueRunner.cpp b/Source/YarnSpinner/Private/DialogueRunner.cpp index eafc862..bb227dd 100644 --- a/Source/YarnSpinner/Private/DialogueRunner.cpp +++ b/Source/YarnSpinner/Private/DialogueRunner.cpp @@ -2,11 +2,10 @@ #include "DialogueRunner.h" + #include "Line.h" #include "Option.h" #include "YarnSubsystem.h" -#include "YarnSpinner.h" -#include "Kismet/KismetInternationalizationLibrary.h" #include "Misc/YSLogging.h" THIRD_PARTY_INCLUDES_START @@ -47,20 +46,20 @@ void ADialogueRunner::PreInitializeComponents() } // Create the Library - Library = TUniquePtr(new Yarn::Library(*this)); + Library = MakeUnique(); // Create the VirtualMachine, supplying it with the loaded Program and // configuring it to use our library, plus use this ADialogueRunner as the // logger and the variable storage - VirtualMachine = TUniquePtr(new Yarn::VirtualMachine(Program, *(Library), *this, *this)); + VirtualMachine = MakeUnique(Program, *(Library), *this); - VirtualMachine->LineHandler = [this](Yarn::Line& Line) + VirtualMachine->OnLine.AddLambda([this](const Yarn::Line& Line) { - UE_LOG(LogYarnSpinner, Log, TEXT("Received line %s"), UTF8_TO_TCHAR(Line.LineID.c_str())); + YS_LOG("Received line %s", *Line.LineID); // Get the Yarn line struct, and make a ULine out of it to use ULine* LineObject = NewObject(this); - LineObject->LineID = FName(Line.LineID.c_str()); + LineObject->LineID = FName(*Line.LineID); GetDisplayTextForLine(LineObject, Line); @@ -68,24 +67,24 @@ void ADialogueRunner::PreInitializeComponents() YS_LOG_FUNC("Got %d line assets for line '%s'", LineAssets.Num(), *LineObject->LineID.ToString()) OnRunLine(LineObject, LineAssets); - }; + }); - VirtualMachine->OptionsHandler = [this](Yarn::OptionSet& OptionSet) + VirtualMachine->OnOptions.AddLambda([this](const Yarn::OptionSet& OptionSet) { - UE_LOG(LogYarnSpinner, Log, TEXT("Received %i options"), OptionSet.Options.size()); + YS_LOG("Received %llu options", OptionSet.Options.Num()); // Build a TArray for every option in this OptionSet TArray Options; - for (auto Option : OptionSet.Options) + for (const Yarn::Option& Option : OptionSet.Options) { - UE_LOG(LogYarnSpinner, Log, TEXT("- %i: %s"), Option.ID, UTF8_TO_TCHAR(Option.Line.LineID.c_str())); + YS_LOG("- %i: %s", Option.ID, *Option.Line.LineID); UOption* Opt = NewObject(this); Opt->OptionID = Option.ID; Opt->Line = NewObject(Opt); - Opt->Line->LineID = FName(Option.Line.LineID.c_str()); + Opt->Line->LineID = FName(*Option.Line.LineID); GetDisplayTextForLine(Opt->Line, Option.Line); @@ -97,47 +96,46 @@ void ADialogueRunner::PreInitializeComponents() } OnRunOptions(Options); - }; + }); - VirtualMachine->DoesFunctionExist = [this](const std::string& FunctionName) -> bool + VirtualMachine->OnCheckFunctionExist.BindLambda([this](const FString& FunctionName) -> bool { - return YarnSubsystem()->GetYarnLibraryRegistry()->HasFunction(FName(UTF8_TO_TCHAR(FunctionName.c_str()))); - }; + return YarnSubsystem()->GetYarnLibraryRegistry()->HasFunction(FName(*FunctionName)); + }); - VirtualMachine->GetExpectedFunctionParamCount = [this](const std::string& FunctionName) -> int + VirtualMachine->OnGetFunctionParamNum.BindLambda([this](const FString& FunctionName) -> int { - return YarnSubsystem()->GetYarnLibraryRegistry()->GetExpectedFunctionParamCount(FName(UTF8_TO_TCHAR(FunctionName.c_str()))); - }; + return YarnSubsystem()->GetYarnLibraryRegistry()->GetExpectedFunctionParamCount(FName(*FunctionName)); + }); - VirtualMachine->CallFunction = [this](const std::string& FunctionName, const std::vector& Parameters) -> Yarn::FValue + VirtualMachine->OnCallFunction.BindLambda([this](const FString& FunctionName, const TArray& Parameters) -> Yarn::FValue { return YarnSubsystem()->GetYarnLibraryRegistry()->CallFunction( - FName(UTF8_TO_TCHAR(FunctionName.c_str())), - TArray(Parameters.data(), Parameters.size()) + FName(*FunctionName), + Parameters ); - }; + }); - VirtualMachine->CommandHandler = [this](Yarn::Command& Command) + VirtualMachine->OnCommand.AddLambda([this](const Yarn::Command& Command) { - UE_LOG(LogYarnSpinner, Log, TEXT("Received command \"%s\""), UTF8_TO_TCHAR(Command.Text.c_str())); + YS_LOG("Received command \"%s\"", *Command.Text); - FString CommandText = FString(UTF8_TO_TCHAR(Command.Text.c_str())); + const FString& CommandText = Command.Text; TArray CommandElements; CommandText.ParseIntoArray(CommandElements, TEXT(" ")); if (CommandElements.Num() == 0) { - TArray EmptyParameters; UE_LOG(LogYarnSpinner, Error, TEXT("Command received, but was unable to parse it.")); - OnRunCommand(FString("(unknown)"), EmptyParameters); + OnRunCommand(FString("(unknown)"), TArray()); return; } - FName CommandName = FName(CommandElements[0]); + const FName CommandName = FName(CommandElements[0]); CommandElements.RemoveAt(0); - auto Lib = YarnSubsystem()->GetYarnLibraryRegistry(); + const UYarnLibraryRegistry* const Lib = YarnSubsystem()->GetYarnLibraryRegistry(); if (Lib->HasCommand(CommandName)) { @@ -150,23 +148,23 @@ void ADialogueRunner::PreInitializeComponents() // Haven't handled the function yet, so call the DialogueRunner's handler OnRunCommand(CommandName.ToString(), CommandElements); - }; + }); - VirtualMachine->NodeStartHandler = [this](std::string NodeName) + VirtualMachine->OnNodeStart.AddLambda( [this](const FString& NodeName) { - UE_LOG(LogYarnSpinner, Log, TEXT("Received node start \"%s\""), UTF8_TO_TCHAR(NodeName.c_str())); - }; + UE_LOG(LogYarnSpinner, Log, TEXT("Received node start \"%s\""), *NodeName); + }); - VirtualMachine->NodeCompleteHandler = [this](std::string NodeName) + VirtualMachine->OnNodeComplete.AddLambda([this](const FString& NodeName) { - UE_LOG(LogYarnSpinner, Log, TEXT("Received node complete \"%s\""), UTF8_TO_TCHAR(NodeName.c_str())); - }; + UE_LOG(LogYarnSpinner, Log, TEXT("Received node complete \"%s\""), *NodeName); + }); - VirtualMachine->DialogueCompleteHandler = [this]() + VirtualMachine->OnDialogueComplete.AddLambda([this]() { UE_LOG(LogYarnSpinner, Log, TEXT("Received dialogue complete")); OnDialogueEnded(); - }; + }); } @@ -223,7 +221,7 @@ void ADialogueRunner::StartDialogue(FName NodeName) return; } - bool bNodeSelected = VirtualMachine->SetNode(TCHAR_TO_UTF8(*NodeName.ToString())); + bool bNodeSelected = VirtualMachine->SetNode(NodeName.ToString()); if (bNodeSelected) { @@ -289,64 +287,44 @@ void ADialogueRunner::SelectOption(UOption* Option) } } - -void ADialogueRunner::Log(std::string Message, Type Severity) -{ - FString MessageText = FString(UTF8_TO_TCHAR(Message.c_str())); - - switch (Severity) - { - case Type::INFO: - YS_LOG("YarnSpinner: %s", *MessageText); - break; - case Type::WARNING: - YS_WARN("YarnSpinner: %s", *MessageText); - break; - case Type::ERROR: - YS_ERR("YarnSpinner: %s", *MessageText); - break; - } -} - - -void ADialogueRunner::SetValue(std::string Name, bool bValue) +void ADialogueRunner::SetValue(const FString& Name, bool bValue) { - YS_LOG("Setting variable %s to bool %i", UTF8_TO_TCHAR(Name.c_str()), bValue) + YS_LOG("Setting variable %s to bool %i", *Name, bValue); YarnSubsystem()->SetValue(Name, bValue); } -void ADialogueRunner::SetValue(std::string Name, float Value) +void ADialogueRunner::SetValue(const FString& Name, float Value) { - YS_LOG("Setting variable %s to float %f", UTF8_TO_TCHAR(Name.c_str()), Value) + YS_LOG("Setting variable %s to float %f", *Name, Value); YarnSubsystem()->SetValue(Name, Value); } -void ADialogueRunner::SetValue(std::string Name, std::string Value) +void ADialogueRunner::SetValue(const FString& Name, const FString& Value) { - YS_LOG("Setting variable %s to string %s", UTF8_TO_TCHAR(Name.c_str()), UTF8_TO_TCHAR(Value.c_str())) + YS_LOG("Setting variable %s to string %s", *Name, *Value); YarnSubsystem()->SetValue(Name, Value); } -bool ADialogueRunner::HasValue(std::string Name) +bool ADialogueRunner::HasValue(const FString& Name) { return YarnSubsystem()->HasValue(Name); } -Yarn::FValue ADialogueRunner::GetValue(std::string Name) +Yarn::FValue ADialogueRunner::GetValue(const FString& Name) { Yarn::FValue Value = YarnSubsystem()->GetValue(Name); - YS_LOG("Retrieving variable %s with value %s", UTF8_TO_TCHAR(Name.c_str()), *Value.ConvertToString()); + YS_LOG("Retrieving variable %s with value %s", *Name, *Value.ConvertToString()); return Value; } -void ADialogueRunner::ClearValue(std::string Name) +void ADialogueRunner::ClearValue(const FString& Name) { - YS_LOG("Clearing variable %s", UTF8_TO_TCHAR(Name.c_str())) + YS_LOG("Clearing variable %s", *Name); YarnSubsystem()->ClearValue(Name); } @@ -364,7 +342,7 @@ UYarnSubsystem* ADialogueRunner::YarnSubsystem() const void ADialogueRunner::GetDisplayTextForLine(ULine* Line, const Yarn::Line& YarnLine) { - const FName LineID = FName(YarnLine.LineID.c_str()); + const FName LineID = FName(*YarnLine.LineID); // This assumes that we only ever care about lines that actually exist in .yarn files (rather than allowing extra lines in .csv files) if (!YarnProject || !YarnProject->Lines.Contains(LineID)) @@ -379,9 +357,9 @@ void ADialogueRunner::GetDisplayTextForLine(ULine* Line, const Yarn::Line& YarnL // Apply substitutions FFormatOrderedArguments FormatArgs; - for (auto Substitution : YarnLine.Substitutions) + for (const FString& Substitution : YarnLine.Substitutions) { - FormatArgs.Emplace(FText::FromString(UTF8_TO_TCHAR(Substitution.c_str()))); + FormatArgs.Emplace(FText::FromString(Substitution)); } const FText TextWithSubstitutions = (LocalisedDisplayText.IsEmptyOrWhitespace()) ? FText::Format(NonLocalisedDisplayText, FormatArgs) : FText::Format(LocalisedDisplayText, FormatArgs); diff --git a/Source/YarnSpinner/Private/Library/YarnFunctionLibrary.cpp b/Source/YarnSpinner/Private/Library/YarnFunctionLibrary.cpp index 5056455..8ca6506 100644 --- a/Source/YarnSpinner/Private/Library/YarnFunctionLibrary.cpp +++ b/Source/YarnSpinner/Private/Library/YarnFunctionLibrary.cpp @@ -143,7 +143,7 @@ TOptional UYarnFunctionLibrary::CallFunction(FName FunctionName, T YS_WARN_FUNC("Could not get return parameter '%s' for function '%s'", *ReturnValue->Name.ToString(), *FunctionName.ToString()) return Result; } - Result = Yarn::FValue(TCHAR_TO_UTF8(*StringParam->GetPropertyValue_InContainer(FuncParams.GetStructMemory()))); + Result = Yarn::FValue(StringParam->GetPropertyValue_InContainer(FuncParams.GetStructMemory())); break; } } diff --git a/Source/YarnSpinner/Private/Library/YarnLibraryRegistry.cpp b/Source/YarnSpinner/Private/Library/YarnLibraryRegistry.cpp index 37fdb50..41ed365 100644 --- a/Source/YarnSpinner/Private/Library/YarnLibraryRegistry.cpp +++ b/Source/YarnSpinner/Private/Library/YarnLibraryRegistry.cpp @@ -293,7 +293,7 @@ void UYarnLibraryRegistry::AddFunction(const FYSLSAction& Func) } else { - Param.Value = Yarn::FValue(TCHAR_TO_UTF8(*InParam.DefaultValue)); + Param.Value = Yarn::FValue(InParam.DefaultValue); } FuncDetail.InParams.Add(Param); @@ -355,7 +355,7 @@ void UYarnLibraryRegistry::AddCommand(const FYSLSAction& Cmd) } else { - Param.Value = Yarn::FValue(TCHAR_TO_UTF8(*InParam.DefaultValue)); + Param.Value = InParam.DefaultValue; } CmdDetail.InParams.Add(Param); diff --git a/Source/YarnSpinner/Private/YarnSpinner.cpp b/Source/YarnSpinner/Private/YarnSpinner.cpp index cc77807..a029aea 100644 --- a/Source/YarnSpinner/Private/YarnSpinner.cpp +++ b/Source/YarnSpinner/Private/YarnSpinner.cpp @@ -2,10 +2,9 @@ #include "YarnSpinner.h" -#include "Modules/ModuleManager.h" -#include "Interfaces/IPluginManager.h" #include "Misc/MessageDialog.h" #include "Misc/YSLogging.h" +#include "Modules/ModuleManager.h" THIRD_PARTY_INCLUDES_START #include @@ -16,9 +15,10 @@ THIRD_PARTY_INCLUDES_END -void UnrealLogHandler(google::protobuf::LogLevel level, const char* filename, int line, - const std::string& message) { - UE_LOG(LogYarnSpinner, Warning, TEXT("Protobuf: %s"), message.c_str()); +void UnrealLogHandler([[maybe_unused]] google::protobuf::LogLevel Level, [[maybe_unused]] const char* Filename, + [[maybe_unused]] int Line, const std::string& Message) +{ + YS_WARN("Protobuf: %hs", Message.c_str()); } diff --git a/Source/YarnSpinner/Private/YarnSpinnerCore/Library.cpp b/Source/YarnSpinner/Private/YarnSpinnerCore/Library.cpp index 9a93eed..835a26f 100644 --- a/Source/YarnSpinner/Private/YarnSpinnerCore/Library.cpp +++ b/Source/YarnSpinner/Private/YarnSpinnerCore/Library.cpp @@ -1,5 +1,8 @@ #include "YarnSpinnerCore/Library.h" +#include "Misc/YSLogging.h" +#include "YarnSpinnerCore/Common.h" + #if defined(_MSC_VER) #pragma warning (disable:4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning) #endif @@ -18,13 +21,13 @@ namespace Yarn { } template - FunctionInfo::FunctionInfo(int paramCount, T (*f)(std::vector)) + FunctionInfo::FunctionInfo(const int ParamCount, T (*F)(const TArray&)) { - Function = f; - ExpectedParameterCount = paramCount; + Function = F; + ExpectedParameterCount = ParamCount; } - Library::Library(ILogger &logger) : logger(logger) + Library::Library() { LoadStandardLibrary(); } @@ -43,45 +46,45 @@ namespace Yarn // Get function template - FunctionInfo Library::GetFunction(std::string name) + FunctionInfo Library::GetFunction(const FString& Name) { - UNUSED(name); + UNUSED(Name); static_assert(dependent_false::value, "Invalid return type for function"); } template <> - FunctionInfo Library::GetFunction(std::string name) + FunctionInfo Library::GetFunction(const FString& name) { return stringFunctions[name]; } template <> - FunctionInfo Library::GetFunction(std::string name) + FunctionInfo Library::GetFunction(const FString& name) { return numberFunctions[name]; } template <> - FunctionInfo Library::GetFunction(std::string name) + FunctionInfo Library::GetFunction(const FString& name) { return boolFunctions[name]; } template - FunctionInfo &Library::GetFunctionImpl(std::map> &source, std::string name) + FunctionInfo &Library::GetFunctionImpl(TMap> &Source, const FString& Name) { - if (source.count(name) == 0) + if (!Source.contains(Name)) { - logger.Log(string_format("Can't get implementation for unknown function '%s'", UTF8_TO_TCHAR(name.c_str()))); + YS_LOG("Can't get implementation for unknown function '%s'", *Name); return FunctionInfo(); } - return source[name]; + return Source[Name]; } // Add Function // template - // void Library::AddFunction (std::string name, T(*f)(std::vector), int parameterCount) { + // void Library::AddFunction (FString name, T(*f)(TArray), int parameterCount) { // // A helper function that can take any function pointer (including lambdas), // // converts them to a YarnFunction, and then forwards that to the regular // // YarnFunction method @@ -90,7 +93,7 @@ namespace Yarn // } template - void Library::AddFunction(std::string name, YarnFunction function, int parameterCount) + void Library::AddFunction(const FString& name, TYarnFunction function, int parameterCount) { UNUSED(name); UNUSED(function); @@ -99,36 +102,36 @@ namespace Yarn } template <> - void Library::AddFunction(std::string name, YarnFunction function, int parameterCount) + void Library::AddFunction(const FString& name, TYarnFunction function, int parameterCount) { AddFunctionImpl(stringFunctions, name, function, parameterCount); } template <> - void Library::AddFunction(std::string name, YarnFunction function, int parameterCount) + void Library::AddFunction(const FString& name, TYarnFunction function, int parameterCount) { AddFunctionImpl(numberFunctions, name, function, parameterCount); } template <> - void Library::AddFunction(std::string name, YarnFunction function, int parameterCount) + void Library::AddFunction(const FString& name, TYarnFunction function, int parameterCount) { AddFunctionImpl(boolFunctions, name, function, parameterCount); } template - void Library::AddFunctionImpl(std::map> &source, std::string name, YarnFunction func, int parameterCount) + void Library::AddFunctionImpl(TMap> &source, const FString& name, TYarnFunction func, int parameterCount) { // Report an error if this function is already defined across any of our // function tables if ( - stringFunctions.count(name) > 0 || - numberFunctions.count(name) > 0 || - boolFunctions.count(name) > 0 || - source.count(name) > 0) // strictly unnecessary but might help catch future bugs + stringFunctions.Contains(name) || + numberFunctions.Contains(name) || + boolFunctions.Contains(name) || + source.Contains(name)) // strictly unnecessary but might help catch future bugs { - logger.Log(string_format("Function %s is already defined", UTF8_TO_TCHAR(name.c_str()))); + YS_LOG("Function %s is already defined", *name); return; } @@ -136,99 +139,96 @@ namespace Yarn FunctionInfo info; info.ExpectedParameterCount = parameterCount; info.Function = func; - source[name] = info; + source.Emplace(name, MoveTemp(info)); } // Remove function template - void Library::RemoveFunction(std::string name) + void Library::RemoveFunction(const FString& Name) { - UNUSED(name); + UNUSED(Name); static_assert(dependent_false::value, "Invalid return type for function"); } template <> - void Library::RemoveFunction(std::string name) + void Library::RemoveFunction(const FString& name) { RemoveFunctionImpl(stringFunctions, name); } template <> - void Library::RemoveFunction(std::string name) + void Library::RemoveFunction(const FString& name) { RemoveFunctionImpl(stringFunctions, name); } template <> - void Library::RemoveFunction(std::string name) + void Library::RemoveFunction(const FString& name) { RemoveFunctionImpl(stringFunctions, name); } template - void Library::RemoveFunctionImpl(std::map> &source, std::string name) + void Library::RemoveFunctionImpl(TMap> &source, const FString& name) { - if (source.count(name) > 0) - { - source.erase(name); - } + source.Remove(name); } // Has Function template - bool Library::HasFunction(std::string name) + bool Library::HasFunction(const FString& Name) { - UNUSED(name); + UNUSED(Name); static_assert(dependent_false::value, "Invalid return type for function"); } template <> - bool Library::HasFunction(std::string name) + bool Library::HasFunction(const FString& name) { - return HasFunctionImpl(stringFunctions, name); + return HasFunctionImpl(stringFunctions, name); } template <> - bool Library::HasFunction(std::string name) + bool Library::HasFunction(const FString& name) { return HasFunctionImpl(numberFunctions, name); } template <> - bool Library::HasFunction(std::string name) + bool Library::HasFunction(const FString& name) { return HasFunctionImpl(boolFunctions, name); } template - bool Library::HasFunctionImpl(std::map> &source, std::string name) + bool Library::HasFunctionImpl(TMap> &source, const FString& name) { - return source.count(name) > 0; + return source.Contains(name); } // Remove all functions void Library::RemoveAllFunctions() { - stringFunctions.clear(); - numberFunctions.clear(); - boolFunctions.clear(); + stringFunctions.Empty(); + numberFunctions.Empty(); + boolFunctions.Empty(); } // Get parameter count - int Library::GetExpectedParameterCount(std::string name) + int Library::GetExpectedParameterCount(const FString& Name) { - if (HasFunction(name)) + if (HasFunction(Name)) { - return GetFunction(name).ExpectedParameterCount; + return GetFunction(Name).ExpectedParameterCount; } - else if (HasFunction(name)) + else if (HasFunction(Name)) { - return GetFunction(name).ExpectedParameterCount; + return GetFunction(Name).ExpectedParameterCount; } - else if (HasFunction(name)) + else if (HasFunction(Name)) { - return GetFunction(name).ExpectedParameterCount; + return GetFunction(Name).ExpectedParameterCount; } else { @@ -240,153 +240,176 @@ namespace Yarn void Library::LoadStandardLibrary() { // Number methods - AddFunction( + AddFunction( "Number.EqualTo", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() == values.at(1).GetValue(); - }, + return Values[0].GetValue() == Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.NotEqualTo", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() != values.at(1).GetValue(); - }, + return Values[0].GetValue() != Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.Add", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() + values.at(1).GetValue(); - }, + return Values[0].GetValue() + Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.Minus", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() - values.at(1).GetValue(); - }, + return Values[0].GetValue() - Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.Divide", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() / values.at(1).GetValue(); - }, + return Values[0].GetValue() / Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.Multiply", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() * values.at(1).GetValue(); - }, + return Values[0].GetValue() * Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.Modulo", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return (int)(values.at(0).GetValue()) % (int)(values.at(1).GetValue()); - }, + return static_cast(Values[0].GetValue()) % static_cast(Values[1].GetValue()); + }), 2); - AddFunction( + AddFunction( "Number.UnaryMinus", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return -(values.at(0).GetValue()); - }, + return -Values[0].GetValue(); + }), 1); - AddFunction( + AddFunction( "Number.GreaterThan", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() > values.at(1).GetValue(); - }, + return Values[0].GetValue() > Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.GreaterThanOrEqualTo", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() >= values.at(1).GetValue(); - }, + return Values[0].GetValue() >= Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.LessThan", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() < values.at(1).GetValue(); - }, + return Values[0].GetValue() < Values[1].GetValue(); + }), 2); - AddFunction( + AddFunction( "Number.LessThanOrEqualTo", - [](std::vector values) + TYarnFunction::CreateLambda( + [](const TArray& Values) { - return values.at(0).GetValue() <= values.at(1).GetValue(); - }, + return Values[0].GetValue() <= Values[1].GetValue(); + }), 2); // Boolean methods - AddFunction( - "Bool.EqualTo", [](std::vector values) - { return values.at(0).GetValue() == values.at(1).GetValue(); }, + AddFunction( + "Bool.EqualTo", + TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() == Values[1].GetValue(); }), 2); - AddFunction( - "Bool.NotEqualTo", [](std::vector values) - { return values.at(0).GetValue() != values.at(1).GetValue(); }, + AddFunction( + "Bool.NotEqualTo", + TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() != Values[1].GetValue(); }), 2); - AddFunction( - "Bool.And", [](std::vector values) - { return values.at(0).GetValue() && values.at(1).GetValue(); }, + AddFunction( + "Bool.And", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() && Values[1].GetValue(); }), 2); - AddFunction( - "Bool.Or", [](std::vector values) - { return values.at(0).GetValue() || values.at(1).GetValue(); }, + AddFunction( + "Bool.Or", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() || Values[1].GetValue(); }), 2); AddFunction( - "Bool.Xor", [](std::vector values) - { return values.at(0).GetValue() ^ values.at(1).GetValue(); }, + "Bool.Xor", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() ^ Values[1].GetValue(); }), 2); - AddFunction( - "Bool.Not", [](std::vector values) - { return !values.at(0).GetValue(); }, + AddFunction( + "Bool.Not", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return !Values[0].GetValue(); }), 1); // String functions - AddFunction( - "String.EqualTo", [](std::vector values) - { return values.at(0).GetValue() == values.at(1).GetValue(); }, + AddFunction( + "String.EqualTo", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() == Values[1].GetValue(); }), 2); - AddFunction( - "String.NotEqualTo", [](std::vector values) - { return values.at(0).GetValue() != values.at(1).GetValue(); }, + AddFunction( + "String.NotEqualTo", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() != Values[1].GetValue(); }), 2); - AddFunction( - "String.Add", [](std::vector values) - { return TCHAR_TO_UTF8(*(values.at(0).GetValue() + values.at(1).GetValue())); }, + AddFunction( + "String.Add", TYarnFunction::CreateLambda( + [](const TArray& Values) + { return Values[0].GetValue() + Values[1].GetValue(); }), 2); } - std::string Library::GenerateUniqueVisitedVariableForNode(std::string nodeName) + FString Library::GenerateUniqueVisitedVariableForNode(const FString& NodeName) { - return "$Yarn.Internal.Visiting." + nodeName; + return FString::Printf(TEXT("$Yarn.Internal.Visiting.%s"), *NodeName); } } diff --git a/Source/YarnSpinner/Private/YarnSpinnerCore/State.cpp b/Source/YarnSpinner/Private/YarnSpinnerCore/State.cpp index ff0425a..6f43f23 100644 --- a/Source/YarnSpinner/Private/YarnSpinnerCore/State.cpp +++ b/Source/YarnSpinner/Private/YarnSpinnerCore/State.cpp @@ -3,77 +3,76 @@ namespace Yarn { - void State::AddOption(Line &line, const char *destination, bool enabled) + void State::AddOption(const Line &Line, const FString& Destination, const bool bEnabled) { auto option = Option(); - option.Line = line; - option.DestinationNode = destination; - option.IsAvailable = enabled; - option.ID = currentOptions.size(); + option.Line = Line; + option.DestinationNode = Destination; + option.IsAvailable = bEnabled; + option.ID = currentOptions.Num(); - currentOptions.push_back(option); + currentOptions.Add(option); } void State::ClearOptions() { - currentOptions.clear(); + currentOptions.Empty(); } - const std::vector