- Added Input/Output compatibility check to event based nodes
- Removed a huge chunk of compatibility checking code out of CMItem
This commit is contained in:
@@ -2223,6 +2223,43 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
internal static bool IsInputCompatible(NodeArchetype nodeArch, ScriptType outputType, ConnectionsHint hint)
|
||||
{
|
||||
// Event based nodes always have a pulse input, so it's always compatible with void
|
||||
if (outputType.IsVoid)
|
||||
return true;
|
||||
|
||||
var eventName = (string)nodeArch.DefaultValues[1];
|
||||
var eventType = TypeUtils.GetType((string)nodeArch.DefaultValues[0]);
|
||||
var member = eventType.GetMember(eventName, MemberTypes.Event, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||
if (member && SurfaceUtils.IsValidVisualScriptEvent(member))
|
||||
{
|
||||
if (!member.IsStatic)
|
||||
{
|
||||
if (VisjectSurface.FullCastCheck(eventType, outputType, hint))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool IsOutputCompatible(NodeArchetype nodeArch, ScriptType inputType, ConnectionsHint hint)
|
||||
{
|
||||
// Event based nodes always have a pulse output, so it's always compatible with void
|
||||
if (inputType.IsVoid)
|
||||
return true;
|
||||
|
||||
var eventName = (string)nodeArch.DefaultValues[1];
|
||||
var eventType = TypeUtils.GetType((string)nodeArch.DefaultValues[0]);
|
||||
var member = eventType.GetMember(eventName, MemberTypes.Event, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
|
||||
if (member && SurfaceUtils.IsValidVisualScriptEvent(member))
|
||||
{
|
||||
if (VisjectSurface.FullCastCheck(member.ValueType, inputType, hint))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class BindEventNode : EventBaseNode
|
||||
@@ -2402,6 +2439,8 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
TypeID = 9,
|
||||
Create = (id, context, arch, groupArch) => new BindEventNode(id, context, arch, groupArch),
|
||||
IsInputCompatible = EventBaseNode.IsInputCompatible,
|
||||
IsOutputCompatible = EventBaseNode.IsOutputCompatible,
|
||||
Title = string.Empty,
|
||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||
Size = new Float2(260, 60),
|
||||
@@ -2424,6 +2463,8 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
TypeID = 10,
|
||||
Create = (id, context, arch, groupArch) => new UnbindEventNode(id, context, arch, groupArch),
|
||||
IsInputCompatible = EventBaseNode.IsInputCompatible,
|
||||
IsOutputCompatible = EventBaseNode.IsOutputCompatible,
|
||||
Title = string.Empty,
|
||||
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI,
|
||||
Size = new Float2(260, 60),
|
||||
|
||||
@@ -109,7 +109,6 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
return false;
|
||||
|
||||
bool isCompatible = false;
|
||||
|
||||
if (startBox.IsOutput && _archetype.IsInputCompatible != null)
|
||||
{
|
||||
isCompatible |= _archetype.IsInputCompatible.Invoke(_archetype, startBox.CurrentType, _archetype.ConnectionsHints);
|
||||
@@ -124,79 +123,6 @@ namespace FlaxEditor.Surface.ContextMenu
|
||||
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)
|
||||
{
|
||||
ScriptMemberInfo memberInfo = ScriptMemberInfo.Null;
|
||||
|
||||
// Check if the archetype tag already has a member info otherwise try to fetch it via the archetype type and name
|
||||
// Only really the InvokeMethod Nodes have a member info in their tag
|
||||
if (_archetype.Tag is ScriptMemberInfo tagInfo)
|
||||
{
|
||||
memberInfo = tagInfo;
|
||||
}
|
||||
else if(_archetype.DefaultValues is { Length: > 1 }) // We have to check since VisualScriptFunctionNode and ReturnNode don't have a name and type
|
||||
{
|
||||
var eventName = (string)_archetype.DefaultValues[1];
|
||||
var eventType = TypeUtils.GetType((string)_archetype.DefaultValues[0]);
|
||||
memberInfo = eventType.GetMember(eventName, System.Reflection.MemberTypes.Event,
|
||||
System.Reflection.BindingFlags.Public |
|
||||
System.Reflection.BindingFlags.Static |
|
||||
System.Reflection.BindingFlags.Instance);
|
||||
}
|
||||
|
||||
if (memberInfo != ScriptMemberInfo.Null)
|
||||
{
|
||||
isCompatible |= CheckMemberInfoCompatibility(startBox, memberInfo);
|
||||
}
|
||||
}*/
|
||||
/*else */
|
||||
|
||||
return isCompatible;
|
||||
}
|
||||
|
||||
private bool CheckMemberInfoCompatibility(Box startBox, ScriptMemberInfo info)
|
||||
{
|
||||
bool isCompatible = false;
|
||||
// Box was dragged from an impulse port and the member info can be invoked so it is compatible
|
||||
if (startBox.CurrentType.IsVoid && info.ValueType.IsVoid)
|
||||
{
|
||||
isCompatible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// When the startBox is output we only need to check the input parameters
|
||||
if (startBox.IsOutput && !info.IsField)
|
||||
{
|
||||
var parameters = info.GetParameters();
|
||||
ScriptType outType = startBox.CurrentType;
|
||||
|
||||
// non static members have an instance input parameter
|
||||
if (!info.IsStatic)
|
||||
{
|
||||
var scriptType = info.DeclaringType;
|
||||
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
|
||||
if (!info.IsEvent)
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
ScriptType inType = parameters[i].Type;
|
||||
isCompatible |= VisjectSurface.FullCastCheck(inType, outType, _archetype.ConnectionsHints);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When the startBox is input we only have to check the output type of the method
|
||||
ScriptType inType = startBox.CurrentType;
|
||||
ScriptType outType = info.ValueType;
|
||||
|
||||
isCompatible |= VisjectSurface.FullCastCheck(inType, outType, _archetype.ConnectionsHints);
|
||||
}
|
||||
}
|
||||
return isCompatible;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user