Add Arrays to Visual Scripting

This commit is contained in:
Wojciech Figat
2021-11-17 19:58:29 +01:00
parent 649059eba1
commit e16c7f3ac4
10 changed files with 492 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
#include "VisjectGraph.h"
#include "GraphUtilities.h"
#include "Engine/Core/Random.h"
#include "Engine/Core/Collections/Sorting.h"
#include "Engine/Core/Math/Vector4.h"
#include "Engine/Core/Math/Transform.h"
#include "Engine/Engine/GameplayGlobals.h"
@@ -16,6 +17,7 @@
#include "Engine/Utilities/StringConverter.h"
#define RAND Random::Rand()
#define ENSURE(condition, errorMsg) if (!(condition)) { OnError(node, box, errorMsg); return; }
VisjectExecutor::VisjectExecutor()
{
@@ -32,6 +34,7 @@ VisjectExecutor::VisjectExecutor()
_perGroupProcessCall[11] = &VisjectExecutor::ProcessGroupBitwise;
_perGroupProcessCall[12] = &VisjectExecutor::ProcessGroupComparisons;
_perGroupProcessCall[14] = &VisjectExecutor::ProcessGroupParticles;
_perGroupProcessCall[18] = &VisjectExecutor::ProcessGroupCollections;
}
VisjectExecutor::~VisjectExecutor()
@@ -1218,6 +1221,109 @@ void VisjectExecutor::ProcessGroupParticles(Box* box, Node* node, Value& value)
}
}
void VisjectExecutor::ProcessGroupCollections(Box* box, Node* node, Value& value)
{
if (node->TypeID < 100)
{
// Array
Variant v = tryGetValue(node->GetBox(0), Value::Null);
ENSURE(v.Type.Type == VariantType::Array, String::Format(TEXT("Input value {0} is not an array."), v));
auto& array = v.AsArray();
Box* b;
switch (node->TypeID)
{
// Count
case 1:
value = array.Count();
break;
// Contains
case 2:
value = array.Contains(tryGetValue(node->GetBox(1), Value::Null));
break;
// Find
case 3:
b = node->GetBox(1);
ENSURE(b->HasConnection(), TEXT("Missing value to find."));
value = array.Find(eatBox(b->GetParent<Node>(), b->FirstConnection()));
break;
// Find Last
case 4:
b = node->GetBox(1);
ENSURE(b->HasConnection(), TEXT("Missing value to find."));
value = array.FindLast(eatBox(b->GetParent<Node>(), b->FirstConnection()));
break;
// Clear
case 5:
array.Clear();
value = MoveTemp(v);
break;
// Remove
case 6:
b = node->GetBox(1);
ENSURE(b->HasConnection(), TEXT("Missing value to remove."));
array.Remove(eatBox(b->GetParent<Node>(), b->FirstConnection()));
value = MoveTemp(v);
break;
// Remove At
case 7:
{
const int32 index = (int32)tryGetValue(node->GetBox(1), 0, Value::Null);
ENSURE(index >= 0 && index < array.Count(), String::Format(TEXT("Array index {0} is out of range [0;{1}]."), index, array.Count() - 1));
array.RemoveAt(index);
value = MoveTemp(v);
break;
}
// Add
case 8:
b = node->GetBox(1);
ENSURE(b->HasConnection(), TEXT("Missing value to add."));
array.Add(eatBox(b->GetParent<Node>(), b->FirstConnection()));
value = MoveTemp(v);
break;
// Insert
case 9:
{
b = node->GetBox(1);
ENSURE(b->HasConnection(), TEXT("Missing value to add."));
const int32 index = (int32)tryGetValue(node->GetBox(2), 0, Value::Null);
ENSURE(index >= 0 && index <= array.Count(), String::Format(TEXT("Array index {0} is out of range [0;{1}]."), index, array.Count()));
array.Insert(index, eatBox(b->GetParent<Node>(), b->FirstConnection()));
value = MoveTemp(v);
break;
}
// Get
case 10:
{
const int32 index = (int32)tryGetValue(node->GetBox(1), 0, Value::Null);
ENSURE(index >= 0 && index < array.Count(), String::Format(TEXT("Array index {0} is out of range [0;{1}]."), index, array.Count() - 1));
value = MoveTemp(array[index]);
break;
}
// Set
case 11:
{
b = node->GetBox(2);
ENSURE(b->HasConnection(), TEXT("Missing value to set."));
const int32 index = (int32)tryGetValue(node->GetBox(1), 0, Value::Null);
ENSURE(index >= 0 && index < array.Count(), String::Format(TEXT("Array index {0} is out of range [0;{1}]."), index, array.Count() - 1));
array[index] = MoveTemp(eatBox(b->GetParent<Node>(), b->FirstConnection()));
value = MoveTemp(v);
break;
}
// Sort
case 12:
Sorting::QuickSort(array.Get(), array.Count());
value = MoveTemp(v);
break;
// Reverse
case 13:
array.Reverse();
value = MoveTemp(v);
break;
}
}
}
VisjectExecutor::Value VisjectExecutor::tryGetValue(Box* box, int32 defaultValueBoxIndex, const Value& defaultValue)
{
const auto parentNode = box->GetParent<Node>();