Communicating from KL -> Canvas

StephenTStephenT Fabric for MotionBuilder Posts: 77

Hi all,

Is it possible to call/trigger/pull canvas graphs from KL code?

I would like to embed graphs within a larger application built mostly in KL. In the KL guide I see a few commands like: dfgPullBlockPort, (haven't tried it yet, but looks like it should be close to what I want) however I don't see any method to interact directly with a graph. For example, is there any way to load a graph? Or test to see if something is loaded?

Has this use case been attempted? Does it make sense? In the worst case, I guess(?) it would be possible to build a C++ extension that exposed the necessary commands, but it would be nice to keep this all in within KL.

Comments

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    Hi Stephen,

    Yes, it is possible to do the most basic things with Canvas graphs from within KL. Here is an example from one of our unit tests:

    operator entry() {
      report("--- Null Binding ---");
      DFGBinding b;
      report("!!b = " + !!b);
    
      report("--- Valid Binding ---");
      b = DFGBinding("
        {
      \"objectType\" : \"Graph\",
      \"title\" : \"\",
      \"ports\" : [
        {
          \"objectType\" : \"Port\",
          \"nodePortType\" : \"Out\",
          \"name\" : \"a\",
          \"execPortType\" : \"In\",
          \"typeSpec\" : \"Float32\"
          },
        {
          \"objectType\" : \"Port\",
          \"metadata\" : {},
          \"nodePortType\" : \"In\",
          \"name\" : \"value\",
          \"execPortType\" : \"Out\",
          \"typeSpec\" : \"Float32\"
          }
        ],
      \"extDeps\" : {},
      \"nodes\" : [
        {
          \"objectType\" : \"Inst\",
          \"metadata\" : {
            \"uiGraphPos\" : \"{\\\"x\\\":280.0,\\\"y\\\":33.0}\"
            },
          \"name\" : \"Add_1\",
          \"ports\" : [
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"lhs\"
              },
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"rhs\"
              },
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"result\"
              }
            ],
          \"executable\" : \"Fabric.Core.Math.Add\",
          \"presetGUID\" : \"8146B3E77857E24CAE33F8B5284585E7\"
          },
        {
          \"objectType\" : \"Inst\",
          \"metadata\" : {
            \"uiGraphPos\" : \"{\\\"x\\\":554.0,\\\"y\\\":33.0}\"
            },
          \"name\" : \"Report_1\",
          \"ports\" : [
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"value\"
              }
            ],
          \"executable\" : \"Fabric.Core.Func.Report\",
          \"presetGUID\" : \"E9448726588111C443C34B2F3D9B0172\"
          }
        ],
      \"connections\" : {
        \"a\" : [
          \"Add_1.lhs\",
          \"Add_1.rhs\"
          ],
        \"Add_1.result\" : [
          \"Report_1.value\"
          ],
        \"Report_1.value\" : [
          \"value\"
          ]
        },
      \"requiredPresets\" : {
        \"Fabric.Core.Math.Add\" : {
          \"objectType\" : \"Func\",
          \"title\" : \"Add\",
          \"ports\" : [
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"lhs\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              },
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"rhs\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              },
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"In\",
              \"name\" : \"result\",
              \"execPortType\" : \"Out\",
              \"typeSpec\" : \"$TYPE$\"
              }
            ],
          \"extDeps\" : {},
          \"presetGUID\" : \"8146B3E77857E24CAE33F8B5284585E7\",
          \"code\" : \"
    dfgEntry {
      result = lhs + rhs;
    }
    \"
          },
        \"Fabric.Core.Func.Report\" : {
          \"objectType\" : \"Func\",
          \"metadata\" : {
            \"uiNodeColor\" : \"{\\n  \\\"r\\\" : 214,\\n  \\\"g\\\" : 191,\\n  \\\"b\\\" : 103\\n  }\",
            \"uiAlwaysShowDaisyChainPorts\" : \"true\",
            \"uiHeaderColor\" : \"{\\n  \\\"r\\\" : 188,\\n  \\\"g\\\" : 129,\\n  \\\"b\\\" : 83\\n  }\"
            },
          \"title\" : \"Report\",
          \"ports\" : [
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"value\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              }
            ],
          \"extDeps\" : {},
          \"presetGUID\" : \"E9448726588111C443C34B2F3D9B0172\",
          \"code\" : \"
    dfgEntry {
      report(value);
    }
    \"
          }
        },
      \"args\" : [
        {
          \"type\" : \"Float32\",
          \"value\" : null
          },
        {
          \"type\" : \"Float32\",
          \"value\" : null
          }
        ]
      }
      ");
      report("!!b = " + !!b);
      report("b.hasErrors() = " + b.hasErrors());
      report("b.getErrors() = " + b.getErrors());
      Count argCount = b.getArgCount();
      report("b.getArgCount() = " + argCount);
      for ( Index i = 0; i < argCount; ++i )
      {
        String argName = b.getArgName(i);
        report("b.getArgName("+i+") = " + argName);
        report("b.getArgPortType("+i+") = " + b.getArgPortType(i));
        report("b.getArgPortType('"+argName+"') = " + b.getArgPortType(argName));
      }
    
      report("Before b.execute()");
      b.execute();
      report("After b.execute()");
    
      report("b.setArgValue(1, RTVal(3.14f32))");
      b.setArgValue(1, RTVal(3.14f32));
      report("Before b.execute()");
      b.execute();
      report("After b.execute()");
      report("b.getArgValue(1) = " + b.getArgValue(1));
    
      report("b.setArgValue(1, RTVal(42))");
      b.setArgValue(1, RTVal(42));
      report("Before b.execute()");
      b.execute();
      report("After b.execute()");
      report("b.getArgValue(1) = " + b.getArgValue(1));
    
      report("b.setArgValue('a', RTVal(13u))");
      b.setArgValue('a', RTVal(13u16));
      report("Before b.execute()");
      b.execute();
      report("After b.execute()");
      report("b.getArgValue('value') = " + b.getArgValue('value'));
    
      report("--- Binding with Errors ---");
      b = DFGBinding("
        {
      \"objectType\" : \"Graph\",
      \"title\" : \"\",
      \"ports\" : [
        {
          \"objectType\" : \"Port\",
          \"nodePortType\" : \"Out\",
          \"name\" : \"a\",
          \"execPortType\" : \"In\",
          \"typeSpec\" : \"Float32\"
          },
        {
          \"objectType\" : \"Port\",
          \"metadata\" : {},
          \"nodePortType\" : \"In\",
          \"name\" : \"value\",
          \"execPortType\" : \"Out\",
          \"typeSpec\" : \"String[]\"
          }
        ],
      \"extDeps\" : {},
      \"nodes\" : [
        {
          \"objectType\" : \"Inst\",
          \"metadata\" : {
            \"uiGraphPos\" : \"{\\\"x\\\":280.0,\\\"y\\\":33.0}\"
            },
          \"name\" : \"Add_1\",
          \"ports\" : [
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"lhs\"
              },
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"rhs\"
              },
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"result\"
              }
            ],
          \"executable\" : \"Fabric.Core.Math.Add\",
          \"presetGUID\" : \"8146B3E77857E24CAE33F8B5284585E7\"
          },
        {
          \"objectType\" : \"Inst\",
          \"metadata\" : {
            \"uiGraphPos\" : \"{\\\"x\\\":554.0,\\\"y\\\":33.0}\"
            },
          \"name\" : \"Report_1\",
          \"ports\" : [
            {
              \"objectType\" : \"InstPort\",
              \"nodePortType\" : \"In\",
              \"name\" : \"value\"
              }
            ],
          \"executable\" : \"Fabric.Core.Func.Report\",
          \"presetGUID\" : \"E9448726588111C443C34B2F3D9B0172\"
          }
        ],
      \"connections\" : {
        \"a\" : [
          \"Add_1.lhs\",
          \"Add_1.rhs\"
          ],
        \"Add_1.result\" : [
          \"Report_1.value\"
          ],
        \"Report_1.value\" : [
          \"value\"
          ]
        },
      \"requiredPresets\" : {
        \"Fabric.Core.Math.Add\" : {
          \"objectType\" : \"Func\",
          \"title\" : \"Add\",
          \"ports\" : [
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"lhs\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              },
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"rhs\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              },
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"In\",
              \"name\" : \"result\",
              \"execPortType\" : \"Out\",
              \"typeSpec\" : \"$TYPE$\"
              }
            ],
          \"extDeps\" : {},
          \"presetGUID\" : \"8146B3E77857E24CAE33F8B5284585E7\",
          \"code\" : \"
    dfgEntry {
      result = lhs + rhs;
    }
    \"
          },
        \"Fabric.Core.Func.Report\" : {
          \"objectType\" : \"Func\",
          \"metadata\" : {
            \"uiNodeColor\" : \"{\\n  \\\"r\\\" : 214,\\n  \\\"g\\\" : 191,\\n  \\\"b\\\" : 103\\n  }\",
            \"uiAlwaysShowDaisyChainPorts\" : \"true\",
            \"uiHeaderColor\" : \"{\\n  \\\"r\\\" : 188,\\n  \\\"g\\\" : 129,\\n  \\\"b\\\" : 83\\n  }\"
            },
          \"title\" : \"Report\",
          \"ports\" : [
            {
              \"objectType\" : \"Port\",
              \"nodePortType\" : \"Out\",
              \"name\" : \"value\",
              \"execPortType\" : \"In\",
              \"typeSpec\" : \"$TYPE$\"
              }
            ],
          \"extDeps\" : {},
          \"presetGUID\" : \"E9448726588111C443C34B2F3D9B0172\",
          \"code\" : \"
    dfgEntry {
      report(value);
    }
    \"
          }
        },
      \"args\" : [
        {
          \"type\" : \"Float32\",
          \"value\" : null
          },
        {
          \"type\" : \"String[]\",
          \"value\" : null
          }
        ]
      }
      ");
      report("b.hasErrors() = " + b.hasErrors());
      report("b.getErrors() = " + b.getErrors());
    }
    

    I think this is covered somewhere in the KL programming guide as well, but this example is probably enough to get you started.

    Peter Zion
    Fabric Engine

  • StephenTStephenT Fabric for MotionBuilder Posts: 77

    Thats fantastic Peter - this is definitely along the lines of what I need (and I found the DFGBinding entry in the docs - thanks!). As always though, there is more :)

    Is it possible to load an unbound preset as an exec, and then create multiple bindings to it? Also - is it possible to get the binding ID so I can post the canvas UI for a specific binding? My goal is to have lots of little graphs for specific jobs in my app, and to post a canvas dialog limited to a particular exec (ideally, to a block within the exec).

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    No there isn't currently. I'll PM you with figuring out about maybe adding this.

    Peter Zion
    Fabric Engine

Sign In or Register to comment.