バージョン 2.3.0 で追加.

Blocks

この章では Canvasにおける block の利用の仔細について記述します。もし Block について馴染みがないのであれば、 Canvasユーザガイドの blockについての章 をまずはじめに参照してください。

Blockについて理解を深めるため、まずは用語について詳しくみていきましょう。「Blocks」とはグラフまたは、関数の中に存在します。グラフまたは関数(一般に「ノード」として呼ばれるものです)のインスタンスにより提供されることで、グラフの代替として振舞ます。このようにインスタンスによって提供されるグラフを「Blockインスタンス」と呼称します。ノードには、グラフあるいは関数(つまりそのノードを定義するもの)の各blockへ、このblockインスタンスを一つ含めることができます。さらに以下に述べるように、入れ子blockにすることで追加の blockインスタンスを公開することもできます。

並列実行(PEX)とBlock

現時点の Canvas では Blockの並列実行は安全ではありません。しかし、並列実行の将来的なサポートは計画に組み込まれています。近い将来にお知らせできると思います。

独自のグラフや関数での Block の使用

グラフの中で、独自のグラフや関数をインラインとして使用したものや、プリセットとして保存した場合に、Block の公開が可能です。ただしグラフあるいは関数どちらであるかに応じて少々異なるやりかたになります。

グラフノードでの Block の公開

block をグラフ中で公開するには、グラフの背景何もない場所を右クリックし、コンテキストメニューの “New Block” を選択、blockを命名します。blockがブロックのような見た目の形状でグラフに登場します。容易に判別つくことでしょう。

注釈

ルートグラフに対しての block作成はできません。できあがった block に定義を与えることができないためです。ルートグラフあるいは blockインスタンスグラフのサブグラフに対してのみ作成することができます。
../_images/cpg-blocks-graph.gif

block の作成ができたのであれば、他のノード同様その blockへとポートを追加、編集、再配置、削除することができます。シフトを押しながらダブルクリックで blockポートエディタが開きます。

関数ノードでの Block の公開

独自関数において Block を公開するには、まずはいつもどおり関数エディタを開きます。エディタの上部付近のタブがいくつかあります。”Ports” タブでポートの追加、編集、削除、再配置ができます。 “Blocks” タブで block の追加と削除ができます。blockの追加には”Blocks” タブに遷移し名前を入力、 “Add Block” をクリックします。新しい block が追加されたら、さらに新しいタブが出現します。新しいタブで blockへのポートの追加が行えます。これらのポートはblockインスタンスの固定ポートとなります。

../_images/cpg-blocks-func.gif

Block が追加されたら、その KL関数コードから blockのポートを引いてくる事ができます。 dfgPullBlockPort コンストラクタを使用します。 dfgPullBlockPort の文法は以下のようになります:

  • dfgPullBlockPort の1番目のパラメータは "blockName.portName" 形式の文字列で、引いてくるblockポートの名前です。
  • input/IOパラメータにはそれぞれ追加パラメータ of non-Execute type があり、この値は blockインスタンスが実行される際に input/IO固定ポートへと提供される値となります。

例として Fabric.Core.Control.ForLoop プリセットを見てみましょう。まず block body が一つあり、入力ポート index を一つ持ち、出力ポート exec も一つ持ちます。KL関数コードではこれを以下のように定義しています。

dfgEntry {
  for ($TYPE$ index = 0; index < count; ++index)
    dfgPullBlockPort('body.exec', index);
}

入れ子Block

あるノードでは、そのノードを定義するグラフあるいは関数中に、blockにblockインスタンスを一つ付ける事ができます。ノードをグラフにより定義している場合、そのノードでは、blockインスタンスの中にさらに blockにblockインスタンスを一つ作ることができます。これをすんなり理解することは難しいでしょう。まずは簡単なもので練習してみましょう。まずは ForLoop をグラフに挿入します。このループの本体の中にさらに block を作成します。追加のblock は ノード(グラフ)上のblockインスタンスとなります。GIFアニメ画像に、 ForLoop プリセット内の入れ子のblockによる、連続した値を生成するグラフの作成過程を示します。

../_images/cpg-blocks-nested.gif

どのように入れ子を活用するかについて Fabric.Compounds.Blocks.Image.Modify プリセットの定義を参考にしてください。

多態性とBlock

Block のポートの多態性についての規則は、通常のグラフや関数のポートについての規則と同様です。型の polymorphism matching 操作は、ノードとノードの Blockインスタンスどちらにも作用します。上述の ForLoop の例では、 count 入力ポートと内部 blockの index 入力ポートがどちらも同じ多態な型 $TYPE を持ちます。

Blockの中での変数

blockインスタンスの中であっても変数を使用することができます。ただし、blockインスタンスの中で変数の宣言を行うと、blockインスタンスの実行毎に、毎度再初期化が走ってしまいます。