- Removed NodeTypeHint
- Added delegates to check compatiblity with custom archetypes - Added compatibility check to InvokeMethod archetype
This commit is contained in:
@@ -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[]
|
||||
{
|
||||
|
||||
@@ -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[]
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the filter.
|
||||
/// </summary>
|
||||
|
||||
@@ -72,28 +72,6 @@ namespace FlaxEditor.Surface
|
||||
/// </summary>
|
||||
All = Scalar | Vector | Enum | Anything | Value | Array | Dictionary,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Node type hint. Helps to distinguish special archetypes
|
||||
/// </summary>
|
||||
[HideInEditor]
|
||||
public enum NodeTypeHint
|
||||
{
|
||||
/// <summary>
|
||||
/// Is Node.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Is Function Node.
|
||||
/// </summary>
|
||||
FunctionNode = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Is custom Packing Node.
|
||||
/// </summary>
|
||||
PackingNode = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Surface node archetype description.
|
||||
@@ -111,6 +89,11 @@ namespace FlaxEditor.Surface
|
||||
/// <returns>The created node object.</returns>
|
||||
public delegate SurfaceNode CreateCustomNodeFunc(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given type is compatible with the given node archetype. Used for custom nodes
|
||||
/// </summary>
|
||||
public delegate bool IsCompatible(NodeArchetype nodeArch, ScriptType portType, ConnectionsHint hint);
|
||||
|
||||
/// <summary>
|
||||
/// Unique node type ID within a single group.
|
||||
/// </summary>
|
||||
@@ -121,6 +104,16 @@ namespace FlaxEditor.Surface
|
||||
/// </summary>
|
||||
public CreateCustomNodeFunc Create;
|
||||
|
||||
/// <summary>
|
||||
/// Function for asynchronously loaded nodes to check if input ports are compatible, for filtering.
|
||||
/// </summary>
|
||||
public IsCompatible IsInputCompatible;
|
||||
|
||||
/// <summary>
|
||||
/// Function for asynchronously loaded nodes to check if output ports are compatible, for filtering.
|
||||
/// </summary>
|
||||
public IsCompatible IsOutputCompatible;
|
||||
|
||||
/// <summary>
|
||||
/// Default initial size of the node.
|
||||
/// </summary>
|
||||
@@ -130,7 +123,7 @@ namespace FlaxEditor.Surface
|
||||
/// Custom set of flags.
|
||||
/// </summary>
|
||||
public NodeFlags Flags;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Title text.
|
||||
/// </summary>
|
||||
@@ -173,11 +166,6 @@ namespace FlaxEditor.Surface
|
||||
/// Connections hints.
|
||||
/// </summary>
|
||||
public ConnectionsHint ConnectionsHints;
|
||||
|
||||
/// <summary>
|
||||
/// Node Type hints.
|
||||
/// </summary>
|
||||
public NodeTypeHint NodeTypeHint;
|
||||
|
||||
/// <summary>
|
||||
/// 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(),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if can use direct conversion from one type to another.
|
||||
|
||||
Reference in New Issue
Block a user