McManning / BlueGraph

Visual Scripting Framework for Unity
MIT License
236 stars 30 forks source link

Add support for inherited Port types #11

Closed McManning closed 3 years ago

McManning commented 3 years ago

For certain use cases, I'd like to be able to inherit off of Port when defining ports on a node. E.g. to optimize Port.GetValue by not boxing value types if I can register typed ports.

McManning commented 3 years ago

I'm going to call this a "won't fix".

If performance is a problem, the right approach is to use the graph editor to generate code for an optimized assembly (which is a use case I'd like to draft out eventually into a different GitHub project). The amount of effort/refactoring required to support safe unboxed variable transfer between nodes outweighs any minor performance benefits.

Granted - I'll likely screw around with the idea in a separate branch but I'm not calling this an expected feature anytime soon.

McManning commented 3 years ago

Might want to put this on the wiki as an example at some point, but I made a quick write up on an alternative if someone really doesn't want to box value types.

Again though, there's plenty of other places to benchmark first before trying to micro-optimize - and if someone is that worried about performance they probably would only be using the graphs at editor/build time anyway.


Rather than using the provided GetInputValue and OnRequestValue methods, you can define your own that don't box values into an object retval:

// Your value type input resolver
public float GetInputFloat(string portName)
{
    var port = GetPort(portName);

    var outputPort = port.ConnectedPorts.First();
    return outputPort.Node.OnRequestFloat(outputPort);
}

// Your value type output resolver
public float OnRequestFloat(Port outputPort)
{
    float foo = GetInputFloat("Foo", this.foo);
    return foo + 1.0f;
}

You would then need to do this for every value type you want to support. Adding a helper interface for your node would probably be useful here:


interface IUseValueTypedPorts
{
    float GetInputFloat(string portName);
    int GetInputInt(string portName);
    string GetInputString(string portName);
    Vector2 GetInputVector2(string portName);
    Vector3 GetInputVector3(string portName);
    Color GetInputColor(string portName);
    // ... and so on.

    float OnRequestFloatValue(Port outputPort);
    int OnRequestInt(Port outputPort);
    string OnRequestString(Port outputPort);
    Vector2 OnRequestVector2(Port outputPort);
    Vector3 OnRequestVector3(Port outputPort);
    Color OnRequestColor(Port outputPort);
    // ... and so on.
}