Add Switch On Enum node
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Surface.Elements;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Surface.Archetypes
|
||||
@@ -39,6 +43,128 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
};
|
||||
}
|
||||
|
||||
private class SwitchOnEnumNode : SurfaceNode
|
||||
{
|
||||
public SwitchOnEnumNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
|
||||
: base(id, context, nodeArch, groupArch)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLoaded()
|
||||
{
|
||||
base.OnLoaded();
|
||||
|
||||
// Restore saved input boxes layout
|
||||
if (Values[0] is byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length / 4; i++)
|
||||
AddBox(false, i + 2, i + 1, string.Empty, new ScriptType(), true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSurfaceLoaded()
|
||||
{
|
||||
base.OnSurfaceLoaded();
|
||||
|
||||
UpdateBoxes();
|
||||
GetBox(0).CurrentTypeChanged += box => UpdateBoxes();
|
||||
}
|
||||
|
||||
public override void ConnectionTick(Box box)
|
||||
{
|
||||
base.ConnectionTick(box);
|
||||
|
||||
UpdateBoxes();
|
||||
}
|
||||
|
||||
private unsafe void UpdateBoxes()
|
||||
{
|
||||
var valueBox = (InputBox)GetBox(0);
|
||||
const int firstBox = 2;
|
||||
const int maxBoxes = 40;
|
||||
bool isInvalid = false;
|
||||
var data = Utils.GetEmptyArray<byte>();
|
||||
|
||||
if (valueBox.HasAnyConnection)
|
||||
{
|
||||
var valueType = valueBox.CurrentType;
|
||||
if (valueType.IsEnum)
|
||||
{
|
||||
// Get enum entries
|
||||
var entries = new List<EnumComboBox.Entry>();
|
||||
EnumComboBox.BuildEntriesDefault(valueType.Type, entries);
|
||||
|
||||
// Setup switch value inputs
|
||||
int id = firstBox;
|
||||
ScriptType type = new ScriptType();
|
||||
for (; id < maxBoxes; id++)
|
||||
{
|
||||
var box = GetBox(id);
|
||||
if (box == null)
|
||||
break;
|
||||
if (box.HasAnyConnection)
|
||||
{
|
||||
type = box.Connections[0].CurrentType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
id = firstBox;
|
||||
for (; id < entries.Count + firstBox; id++)
|
||||
{
|
||||
var e = entries[id - firstBox];
|
||||
var box = AddBox(false, id, id - 1, e.Name, type, true);
|
||||
if (!string.IsNullOrEmpty(e.Tooltip))
|
||||
box.TooltipText = e.Tooltip;
|
||||
}
|
||||
for (; id < maxBoxes; id++)
|
||||
{
|
||||
var box = GetBox(id);
|
||||
if (box == null)
|
||||
break;
|
||||
RemoveElement(box);
|
||||
}
|
||||
|
||||
// Setup output
|
||||
var outputBox = (OutputBox)GetBox(1);
|
||||
outputBox.CurrentType = type;
|
||||
|
||||
// Build data about enum entries values for the runtime
|
||||
if (Values[0] is byte[] dataPrev && dataPrev.Length == entries.Count * 4)
|
||||
data = dataPrev;
|
||||
else
|
||||
data = new byte[entries.Count * 4];
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
int* dataValues = (int*)dataPtr;
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
dataValues[i] = entries[i].Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not an enum
|
||||
isInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInvalid)
|
||||
{
|
||||
// Remove input values boxes if switch value is unused
|
||||
for (int id = firstBox; id < maxBoxes; id++)
|
||||
{
|
||||
var box = GetBox(id);
|
||||
if (box == null)
|
||||
break;
|
||||
RemoveElement(box);
|
||||
}
|
||||
}
|
||||
|
||||
Values[0] = data;
|
||||
|
||||
ResizeAuto();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The nodes for that group.
|
||||
/// </summary>
|
||||
@@ -81,6 +207,22 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
NodeElementArchetype.Factory.Output(0, string.Empty, null, 3)
|
||||
}
|
||||
},
|
||||
new NodeArchetype
|
||||
{
|
||||
TypeID = 8,
|
||||
Title = "Switch On Enum",
|
||||
Create = (id, context, arch, groupArch) => new SwitchOnEnumNode(id, context, arch, groupArch),
|
||||
Description = "Returns one of the input values based on the enum value",
|
||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,
|
||||
Size = new Vector2(160, 60),
|
||||
DefaultValues = new object[] { Utils.GetEmptyArray<byte>() },
|
||||
ConnectionsHints = ConnectionsHint.Enum,
|
||||
Elements = new[]
|
||||
{
|
||||
NodeElementArchetype.Factory.Input(0, "Value", true, null, 0),
|
||||
NodeElementArchetype.Factory.Output(0, string.Empty, null, 1),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -860,6 +860,28 @@ void VisjectExecutor::ProcessGroupComparisons(Box* box, Node* node, Value& value
|
||||
else
|
||||
value = tryGetValue(node->GetBox(1), 0, Value::Zero);
|
||||
break;
|
||||
}
|
||||
// Switch On Enum
|
||||
case 8:
|
||||
{
|
||||
const Value v = tryGetValue(node->GetBox(0), Value::Null);
|
||||
if (v.Type.Type == VariantType::Enum && node->Values.Count() == 1 && node->Values[0].Type.Type == VariantType::Blob)
|
||||
{
|
||||
int32* dataValues = (int32*)node->Values[0].AsBlob.Data;
|
||||
int32 dataValuesCount = node->Values[0].AsBlob.Length / 4;
|
||||
int32 vAsInt = (int32)v;
|
||||
for (int32 i = 0; i < dataValuesCount; i++)
|
||||
{
|
||||
if (dataValues[i] == vAsInt)
|
||||
{
|
||||
value = tryGetValue(node->GetBox(i + 2), Value::Null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
value = Value::Null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user