diff --git a/Source/Editor/Surface/Archetypes/Function.cs b/Source/Editor/Surface/Archetypes/Function.cs
index d027dd8f1..422ebf35b 100644
--- a/Source/Editor/Surface/Archetypes/Function.cs
+++ b/Source/Editor/Surface/Archetypes/Function.cs
@@ -773,7 +773,7 @@ namespace FlaxEditor.Surface.Archetypes
Values[4] = GetSignatureData(memberInfo, memberInfo.GetParameters());
}
}
-
+
private SignatureInfo LoadSignature()
{
var signature = new SignatureInfo();
@@ -1151,6 +1151,45 @@ namespace FlaxEditor.Surface.Archetypes
base.OnDestroy();
}
+
+ internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint)
+ {
+ if (nodeArch.Tag is not ScriptMemberInfo memberInfo)
+ return false;
+ if(memberInfo.ValueType.IsVoid && outputType.IsVoid)
+ return true;
+ if (!memberInfo.IsStatic)
+ {
+ if (VisjectSurface.FullCastCheck(memberInfo.DeclaringType, outputType, hint))
+ return true;
+ }
+ foreach (var param in memberInfo.GetParameters())
+ {
+ if(param.IsOut)
+ continue;
+ if (VisjectSurface.FullCastCheck(param.Type, outputType, hint))
+ return true;
+ }
+ return false;
+ }
+
+ internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint)
+ {
+ if (nodeArch.Tag is not ScriptMemberInfo memberInfo)
+ return false;
+ if(memberInfo.ValueType.IsVoid && inputType.IsVoid)
+ return true;
+ if (VisjectSurface.FullCastCheck(memberInfo.ValueType, inputType, hint))
+ return true;
+ foreach (var param in memberInfo.GetParameters())
+ {
+ if(!param.IsOut)
+ continue;
+ if (VisjectSurface.FullCastCheck(param.Type, inputType, hint))
+ return true;
+ }
+ return false;
+ }
}
private sealed class ReturnNode : SurfaceNode
@@ -2228,7 +2267,6 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Function Input",
Description = "The graph function input data",
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2248,7 +2286,6 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Function Output",
Description = "The graph function output data",
Flags = NodeFlags.MaterialGraph | NodeFlags.ParticleEmitterGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaPaste,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2267,7 +2304,6 @@ namespace FlaxEditor.Surface.Archetypes
Title = string.Empty,
Description = "Overrides the base class method with custom implementation",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2280,9 +2316,10 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 4,
Create = (id, context, arch, groupArch) => new InvokeMethodNode(id, context, arch, groupArch),
+ IsInputCompatible = InvokeMethodNode.IsInputCompatible,
+ IsOutputCompatible = InvokeMethodNode.IsOutputCompatible,
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2306,7 +2343,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new ReturnNode(id, context, arch, groupArch),
Title = "Return",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(100, 40),
DefaultValues = new object[]
{
@@ -2325,7 +2361,6 @@ namespace FlaxEditor.Surface.Archetypes
Title = "New Function",
Description = "Adds a new function to the script",
Flags = NodeFlags.VisualScriptGraph,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 20),
DefaultValues = new object[]
{
@@ -2338,7 +2373,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new GetFieldNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2354,7 +2388,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new SetFieldNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(240, 60),
DefaultValues = new object[]
{
@@ -2371,7 +2404,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new BindEventNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(260, 60),
DefaultValues = new object[]
{
@@ -2394,7 +2426,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new UnbindEventNode(id, context, arch, groupArch),
Title = string.Empty,
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.FunctionNode,
Size = new Float2(260, 60),
DefaultValues = new object[]
{
diff --git a/Source/Editor/Surface/Archetypes/Packing.cs b/Source/Editor/Surface/Archetypes/Packing.cs
index 54524dc13..5a5e9cd5b 100644
--- a/Source/Editor/Surface/Archetypes/Packing.cs
+++ b/Source/Editor/Surface/Archetypes/Packing.cs
@@ -353,7 +353,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new PackStructureNode(id, context, arch, groupArch),
Description = "Makes the structure data to from the components.",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.PackingNode,
Size = new Float2(180, 20),
DefaultValues = new object[]
{
@@ -464,7 +463,6 @@ namespace FlaxEditor.Surface.Archetypes
Create = (id, context, arch, groupArch) => new UnpackStructureNode(id, context, arch, groupArch),
Description = "Breaks the structure data to allow extracting components from it.",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph | NodeFlags.NoSpawnViaGUI,
- NodeTypeHint = NodeTypeHint.PackingNode,
Size = new Float2(180, 20),
DefaultValues = new object[]
{
diff --git a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
index 65ba19909..1d645a94e 100644
--- a/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
+++ b/Source/Editor/Surface/ContextMenu/VisjectCMItem.cs
@@ -109,9 +109,23 @@ namespace FlaxEditor.Surface.ContextMenu
return false;
bool isCompatible = false;
+
+ if (startBox.IsOutput && _archetype.IsInputCompatible != null)
+ {
+ isCompatible |= _archetype.IsInputCompatible.Invoke(_archetype, startBox.CurrentType, _archetype.ConnectionsHints);
+ }
+ else if (!startBox.IsOutput && _archetype.IsOutputCompatible != null)
+ {
+ isCompatible |= _archetype.IsOutputCompatible.Invoke(_archetype, startBox.CurrentType, startBox.ParentNode.Archetype.ConnectionsHints);
+ }
+ else if (_archetype.Elements != null)
+ {
+ // Check compatibility based on the defined elements in the archetype. This handles all the default groups and items
+ isCompatible = CheckElementsCompatibility(startBox);
+ }
// Check compatibility based on the archetype tag or name. This handles custom groups and items, mainly function nodes for visual scripting
- if (_archetype.NodeTypeHint is NodeTypeHint.FunctionNode)
+ /*if (_archetype.NodeTypeHint is NodeTypeHint.FunctionNode)
{
ScriptMemberInfo memberInfo = ScriptMemberInfo.Null;
@@ -135,12 +149,8 @@ namespace FlaxEditor.Surface.ContextMenu
{
isCompatible |= CheckMemberInfoCompatibility(startBox, memberInfo);
}
- }
- else if (_archetype.Elements != null)
- {
- // Check compatibility based on the defined elements in the archetype. This handles all the default groups and items
- isCompatible = CheckElementsCompatibility(startBox);
- }
+ }*/
+ /*else */
return isCompatible;
}
@@ -165,17 +175,16 @@ namespace FlaxEditor.Surface.ContextMenu
if (!info.IsStatic)
{
var scriptType = info.DeclaringType;
- isCompatible |= CanCastType(scriptType, outType, _archetype.ConnectionsHints);
+ isCompatible |= VisjectSurface.FullCastCheck(scriptType, outType, _archetype.ConnectionsHints);
}
// We ignore event members here since they only have output parameters, which are currently not declared as such
- // TODO: Fix bug where event member parameters 'IsOut' is set to false and not true
if (!info.IsEvent)
{
for (int i = 0; i < parameters.Length; i++)
{
ScriptType inType = parameters[i].Type;
- isCompatible |= CanCastType(inType, outType, _archetype.ConnectionsHints);
+ isCompatible |= VisjectSurface.FullCastCheck(inType, outType, _archetype.ConnectionsHints);
}
}
}
@@ -185,7 +194,7 @@ namespace FlaxEditor.Surface.ContextMenu
ScriptType inType = startBox.CurrentType;
ScriptType outType = info.ValueType;
- isCompatible |= CanCastType(inType, outType, _archetype.ConnectionsHints);
+ isCompatible |= VisjectSurface.FullCastCheck(inType, outType, _archetype.ConnectionsHints);
}
}
return isCompatible;
@@ -220,25 +229,12 @@ namespace FlaxEditor.Surface.ContextMenu
hint = startBox.ParentNode.Archetype.ConnectionsHints;
}
- isCompatible |= CanCastType(fromType, toType, hint);
+ isCompatible |= VisjectSurface.FullCastCheck(fromType, toType, hint);
}
return isCompatible;
}
- private bool CanCastType(ScriptType from, ScriptType to, ConnectionsHint hint)
- {
- // Yes, from and to are switched on purpose
- if (VisjectSurface.CanUseDirectCastStatic(to, from, false))
- return true;
-
- if(VisjectSurface.IsTypeCompatible(from, to, hint))
- return true;
-
- // Same here
- return to.CanCastTo(from);
- }
-
///
/// Updates the filter.
///
diff --git a/Source/Editor/Surface/NodeArchetype.cs b/Source/Editor/Surface/NodeArchetype.cs
index 146618ae7..1a7f88f20 100644
--- a/Source/Editor/Surface/NodeArchetype.cs
+++ b/Source/Editor/Surface/NodeArchetype.cs
@@ -72,28 +72,6 @@ namespace FlaxEditor.Surface
///
All = Scalar | Vector | Enum | Anything | Value | Array | Dictionary,
}
-
- ///
- /// Node type hint. Helps to distinguish special archetypes
- ///
- [HideInEditor]
- public enum NodeTypeHint
- {
- ///
- /// Is Node.
- ///
- Default = 0,
-
- ///
- /// Is Function Node.
- ///
- FunctionNode = 1,
-
- ///
- /// Is custom Packing Node.
- ///
- PackingNode = 2,
- }
///
/// Surface node archetype description.
@@ -111,6 +89,11 @@ namespace FlaxEditor.Surface
/// The created node object.
public delegate SurfaceNode CreateCustomNodeFunc(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch);
+ ///
+ /// Checks if the given type is compatible with the given node archetype. Used for custom nodes
+ ///
+ public delegate bool IsCompatible(NodeArchetype nodeArch, ScriptType portType, ConnectionsHint hint);
+
///
/// Unique node type ID within a single group.
///
@@ -121,6 +104,16 @@ namespace FlaxEditor.Surface
///
public CreateCustomNodeFunc Create;
+ ///
+ /// Function for asynchronously loaded nodes to check if input ports are compatible, for filtering.
+ ///
+ public IsCompatible IsInputCompatible;
+
+ ///
+ /// Function for asynchronously loaded nodes to check if output ports are compatible, for filtering.
+ ///
+ public IsCompatible IsOutputCompatible;
+
///
/// Default initial size of the node.
///
@@ -130,7 +123,7 @@ namespace FlaxEditor.Surface
/// Custom set of flags.
///
public NodeFlags Flags;
-
+
///
/// Title text.
///
@@ -173,11 +166,6 @@ namespace FlaxEditor.Surface
/// Connections hints.
///
public ConnectionsHint ConnectionsHints;
-
- ///
- /// Node Type hints.
- ///
- public NodeTypeHint NodeTypeHint;
///
/// Array with independent boxes IDs.
@@ -211,6 +199,8 @@ namespace FlaxEditor.Surface
{
TypeID = TypeID,
Create = Create,
+ IsInputCompatible = IsInputCompatible,
+ IsOutputCompatible = IsOutputCompatible,
Size = Size,
Flags = Flags,
Title = Title,
@@ -220,7 +210,6 @@ namespace FlaxEditor.Surface
DefaultValues = (object[])DefaultValues?.Clone(),
DefaultType = DefaultType,
ConnectionsHints = ConnectionsHints,
- NodeTypeHint = NodeTypeHint,
IndependentBoxes = (int[])IndependentBoxes?.Clone(),
DependentBoxes = (int[])DependentBoxes?.Clone(),
Elements = (NodeElementArchetype[])Elements?.Clone(),
diff --git a/Source/Editor/Surface/VisjectSurface.Connecting.cs b/Source/Editor/Surface/VisjectSurface.Connecting.cs
index 449f88f8c..9ca4f82e8 100644
--- a/Source/Editor/Surface/VisjectSurface.Connecting.cs
+++ b/Source/Editor/Surface/VisjectSurface.Connecting.cs
@@ -199,6 +199,17 @@ namespace FlaxEditor.Surface
return false;
}
+
+ public static bool FullCastCheck(ScriptType from, ScriptType to, ConnectionsHint hint)
+ {
+ // Yes, from and to are switched on purpose
+ if (CanUseDirectCastStatic(to, from, false))
+ return true;
+ if(IsTypeCompatible(from, to, hint))
+ return true;
+ // Same here
+ return to.CanCastTo(from);
+ }
///
/// Checks if can use direct conversion from one type to another.