I would like a reference from SimplexNodeWrapper to simplexNode.

FlowCanvas Forums Support I would like a reference from SimplexNodeWrapper to simplexNode.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #3587
    tanitakatech
    Participant

    Hello, thank you for the wonderful asset.

    I am currently creating an extension for FlowCanvas and I want to be able to reference simplexNode from SimplecNodeWrapper.
    Here is an example of the implementation.
    csharp
    abstract public class SimplexNodeWrapper : FlowNode
    {
    public abstract object SimplexNodeReference { get; }
    }

    ///<summary>Wraps a SimplexNode</summary>
    public class SimplexNodeWrapper<T> : SimplexNodeWrapper where T : SimplexNode
    {
    public override object SimplexNodeReference => simplexNode;
    // other code
    }
    <code></code>

    Use case
    I am trying to create an extension that automatically inserts values at graph initialization time when the Inject attribute is attached to the fields of custom nodes.
    The nodes that can be obtained from allNodes are of type Node, but it seemed impossible in C# to cast from here to SimplexNodeWrapper<T> and get simplexNode.
    (Because it is not possible to cast without directly specifying the generic argument.)

    csharp
    public class InjectableFlowScript : FlowCanvas.FlowGraph
    {
    protected override void OnGraphInitialize()
    {
    base.OnGraphInitialize();

    foreach (var node in allNodes)
    {
    InjectFields(node);
    }
    }

    private void InjectFields(Node node)
    {
    var type = GetNodeType(node);
    var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    foreach (var field in fields)
    {
    TryInjectField(field, node);
    }

    var parentFields = type.BaseType?.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    if (parentFields != null)
    {
    foreach (var field in parentFields)
    {
    TryInjectField(field, node);
    }
    }
    }

    private Type GetNodeType(Node node)
    {
    return node is SimplexNodeWrapper simplexNodeWrapper
    ? node.GetType().GetGenericArguments()[0] ?? node.GetType()
    : node.GetType();
    }

    private void TryInjectField(FieldInfo field, Node node)
    {
    if (!Attribute.IsDefined(field, typeof(InjectAttribute)))
    {
    return;
    }

    var variable = blackboard.GetVariable(field.FieldType.Name, field.FieldType);
    if (variable != null && node is SimplexNodeWrapper simplexNodeWrapper)
    {
    field.SetValue(simplexNodeWrapper.SimplexNodeReference, variable.value);
    }
    }
    }
    <code></code>

    #3594
    Gavalakis
    Keymaster

    Hello and sorry for the late reply. I am glad you like FlowCanvas, thanks πŸ™‚
    SimplexNodes are implemented in a way that differentiate them from “normal” nodes (meaning all those deriving from FlowNode) and this has some restrictions, even though they were implemented this way for straightforward ease of creating nodes.
    If you want total control over your nodes like in your example, may I suggest that you instead create your custom nodes by deriving from FlowNode rather than creating SimplexNodes? This will give you all the control you need since FlowNodes are Nodes, while SimplexNodes, well.. are something different πŸ™‚

    With that said, I can of course implement your suggestion to be able to reference the SimplexNode from within SimplexNodeWrapper, but I would still suggest creating custom nodes deriving FlowNodes for more control like in your use case.

    Let me know what you think.
    Thanks!

    Join us on Discord: https://discord.gg/97q2Rjh

    #3595
    tanitakatech
    Participant

    Thank you for your polite reply!

    I realize this might be quite unusual, but initially, I was validating with a graph composed solely of LatentActionNodes, which led me to mistakenly believe that all nodes were composed of SimplexNodeWrappers.

    One concern I have with using custom nodes that inherit from FlowNode is the difficulty in maintaining consistency in the behavior of the Inject attribute across different nodes. For instance, I’d prefer to avoid a situation where the behavior of attributes changes depending on the node class inherited.

    I plan to release the library I am currently working on as open source once it is more refined. I hope to then discuss the possibility of implementing the same features in FlowCanvas. For now, I am proceeding with my work by modifying the SimplexNodeWrapper.

    I understand that adding properties not referenced anywhere solely for user extensibility might be tough, so my attitude is more of a β€œit would be nice to have.” However, once the library is complete, I would be grateful to discuss it further.

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.