- Implemented function node and bind/unbind node compatiblility/filtering
- Added NodeTypeHint enum
This commit is contained in:
@@ -2228,6 +2228,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = "Function Input",
|
Title = "Function Input",
|
||||||
Description = "The graph function input data",
|
Description = "The graph function input data",
|
||||||
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
|
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2247,6 +2248,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = "Function Output",
|
Title = "Function Output",
|
||||||
Description = "The graph function output data",
|
Description = "The graph function output data",
|
||||||
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
|
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2265,6 +2267,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Description = "Overrides the base class method with custom implementation",
|
Description = "Overrides the base class method with custom implementation",
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2279,6 +2282,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new InvokeMethodNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new InvokeMethodNode(id, context, arch, groupArch),
|
||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2302,6 +2306,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new ReturnNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new ReturnNode(id, context, arch, groupArch),
|
||||||
Title = "Return",
|
Title = "Return",
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(100, 40),
|
Size = new Float2(100, 40),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2320,6 +2325,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Title = "New Function",
|
Title = "New Function",
|
||||||
Description = "Adds a new function to the script",
|
Description = "Adds a new function to the script",
|
||||||
Flags = NodeFlags.VisualScriptGraph,
|
Flags = NodeFlags.VisualScriptGraph,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 20),
|
Size = new Float2(240, 20),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2332,6 +2338,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new GetFieldNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new GetFieldNode(id, context, arch, groupArch),
|
||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2347,6 +2354,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new SetFieldNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new SetFieldNode(id, context, arch, groupArch),
|
||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(240, 60),
|
Size = new Float2(240, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2363,6 +2371,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new BindEventNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new BindEventNode(id, context, arch, groupArch),
|
||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(260, 60),
|
Size = new Float2(260, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
@@ -2385,6 +2394,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Create = (id, context, arch, groupArch) => new UnbindEventNode(id, context, arch, groupArch),
|
Create = (id, context, arch, groupArch) => new UnbindEventNode(id, context, arch, groupArch),
|
||||||
Title = string.Empty,
|
Title = string.Empty,
|
||||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||||
|
NodeTypeHint = NodeTypeHint.FunctionNode,
|
||||||
Size = new Float2(260, 60),
|
Size = new Float2(260, 60),
|
||||||
DefaultValues = new object[]
|
DefaultValues = new object[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Surface.Elements;
|
using FlaxEditor.Surface.Elements;
|
||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.Surface.ContextMenu
|
namespace FlaxEditor.Surface.ContextMenu
|
||||||
{
|
{
|
||||||
@@ -121,13 +123,70 @@ namespace FlaxEditor.Surface.ContextMenu
|
|||||||
Visible = true;
|
Visible = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_archetype?.Elements == null)
|
if (_archetype == null)
|
||||||
{
|
{
|
||||||
Visible = false;
|
Visible = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isCompatible = false;
|
||||||
|
if (_archetype.Elements != null)
|
||||||
|
{
|
||||||
|
isCompatible = CheckElementsCompatibility(startBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_archetype.NodeTypeHint == NodeTypeHint.FunctionNode)
|
||||||
|
{
|
||||||
|
isCompatible = false;
|
||||||
|
ScriptMemberInfo memberInfo = ScriptMemberInfo.Null;
|
||||||
|
|
||||||
|
if (_archetype.Tag is ScriptMemberInfo info)
|
||||||
|
{
|
||||||
|
memberInfo = info;
|
||||||
|
}
|
||||||
|
else if(_archetype.DefaultValues is { Length: > 1 })
|
||||||
|
{
|
||||||
|
var eventName = (string)_archetype.DefaultValues[1];
|
||||||
|
var eventType = TypeUtils.GetType((string)_archetype.DefaultValues[0]);
|
||||||
|
memberInfo = eventType.GetMember(eventName, MemberTypes.Event, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memberInfo != ScriptMemberInfo.Null)
|
||||||
|
{
|
||||||
|
if (startBox.IsOutput)
|
||||||
|
{
|
||||||
|
var parameters = memberInfo.GetParameters();
|
||||||
|
ScriptType outType = startBox.CurrentType;
|
||||||
|
|
||||||
|
if (!memberInfo.IsStatic)
|
||||||
|
{
|
||||||
|
var scriptType = TypeUtils.GetType((string)_archetype.DefaultValues[0]);
|
||||||
|
isCompatible |= CanCastToType(scriptType, outType, _archetype.ConnectionsHints);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memberInfo.IsEvent)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
ScriptType inType = parameters[i].Type;
|
||||||
|
isCompatible |= CanCastToType(inType, outType, _archetype.ConnectionsHints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Visible = isCompatible;
|
||||||
|
return isCompatible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckElementsCompatibility(Box startBox)
|
||||||
|
{
|
||||||
bool isCompatible = false;
|
bool isCompatible = false;
|
||||||
foreach (NodeElementArchetype element in _archetype.Elements)
|
foreach (NodeElementArchetype element in _archetype.Elements)
|
||||||
{
|
{
|
||||||
@@ -153,15 +212,12 @@ namespace FlaxEditor.Surface.ContextMenu
|
|||||||
hint = startBox.ParentNode.Archetype.ConnectionsHints;
|
hint = startBox.ParentNode.Archetype.ConnectionsHints;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkCompatibility = CanCastToType(inType, outType, hint);
|
isCompatible |= CanCastToType(inType, outType, hint);
|
||||||
isCompatible |= checkCompatibility;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Visible = isCompatible;
|
|
||||||
|
|
||||||
return isCompatible;
|
return isCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanCastToType(ScriptType currentType, ScriptType type, ConnectionsHint hint)
|
private bool CanCastToType(ScriptType currentType, ScriptType type, ConnectionsHint hint)
|
||||||
{
|
{
|
||||||
if (VisjectSurface.CanUseDirectCastStatic(type, currentType, false))
|
if (VisjectSurface.CanUseDirectCastStatic(type, currentType, false))
|
||||||
|
|||||||
@@ -73,6 +73,20 @@ namespace FlaxEditor.Surface
|
|||||||
All = Scalar | Vector | Enum | Anything | Value | Array | Dictionary,
|
All = Scalar | Vector | Enum | Anything | Value | Array | Dictionary,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HideInEditor]
|
||||||
|
public enum NodeTypeHint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Is Node.
|
||||||
|
/// </summary>
|
||||||
|
Default = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is Function Node.
|
||||||
|
/// </summary>
|
||||||
|
FunctionNode = 1,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Surface node archetype description.
|
/// Surface node archetype description.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -152,6 +166,11 @@ namespace FlaxEditor.Surface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ConnectionsHint ConnectionsHints;
|
public ConnectionsHint ConnectionsHints;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node Type hints.
|
||||||
|
/// </summary>
|
||||||
|
public NodeTypeHint NodeTypeHint;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Array with independent boxes IDs.
|
/// Array with independent boxes IDs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -193,6 +212,7 @@ namespace FlaxEditor.Surface
|
|||||||
DefaultValues = (object[])DefaultValues?.Clone(),
|
DefaultValues = (object[])DefaultValues?.Clone(),
|
||||||
DefaultType = DefaultType,
|
DefaultType = DefaultType,
|
||||||
ConnectionsHints = ConnectionsHints,
|
ConnectionsHints = ConnectionsHints,
|
||||||
|
NodeTypeHint = NodeTypeHint,
|
||||||
IndependentBoxes = (int[])IndependentBoxes?.Clone(),
|
IndependentBoxes = (int[])IndependentBoxes?.Clone(),
|
||||||
DependentBoxes = (int[])DependentBoxes?.Clone(),
|
DependentBoxes = (int[])DependentBoxes?.Clone(),
|
||||||
Elements = (NodeElementArchetype[])Elements?.Clone(),
|
Elements = (NodeElementArchetype[])Elements?.Clone(),
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ namespace FlaxEditor.Surface
|
|||||||
bindNode.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
|
bindNode.Description = SurfaceUtils.GetVisualScriptMemberInfoDescription(member);
|
||||||
bindNode.SubTitle = string.Format(" (in {0})", scriptTypeName);
|
bindNode.SubTitle = string.Format(" (in {0})", scriptTypeName);
|
||||||
((IList<NodeArchetype>)group.Archetypes).Add(bindNode);
|
((IList<NodeArchetype>)group.Archetypes).Add(bindNode);
|
||||||
|
|
||||||
// Add Unbind event node
|
// Add Unbind event node
|
||||||
var unbindNode = (NodeArchetype)Archetypes.Function.Nodes[9].Clone();
|
var unbindNode = (NodeArchetype)Archetypes.Function.Nodes[9].Clone();
|
||||||
unbindNode.DefaultValues[0] = scriptTypeTypeName;
|
unbindNode.DefaultValues[0] = scriptTypeTypeName;
|
||||||
@@ -589,6 +589,7 @@ namespace FlaxEditor.Surface
|
|||||||
node.DefaultValues[0] = name;
|
node.DefaultValues[0] = name;
|
||||||
node.DefaultValues[1] = parameters.Length;
|
node.DefaultValues[1] = parameters.Length;
|
||||||
node.Title = "Override " + name;
|
node.Title = "Override " + name;
|
||||||
|
node.Tag = member;
|
||||||
nodes.Add(node);
|
nodes.Add(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user