treenode
説明
FlexSimのツリーに存在するノードへの参照を表すクラスです。
treenodeクラスは、FlexSimのツリーにおいてアクセスするすべてのオブジェクトおよびノードの基本となるクラスです。オブジェクトデータを持つノードに特有のデータおよび機能についてはObjectクラスを使用することでさまざまなものにアクセスできますが、treenodeは最も基本のインターフェースです。最初に、ツリー構造自体に関連付けられたデータおよび機能が利用可能になります。2番目に、ノード自体に格納された基本データ(ノード名およびデータ値)が利用可能になります。3番目に、非常にたくさんのモデリングロジックがラベルを使用するため、treenodeクラスはオブジェクト、トークン、およびタスクシーケンス上でラベルを簡単に操作するメカニズムを提供しています。
treenodeクラスはObjectなどのサブクラスに自動でダウンキャストできます。
treenode src = model().find("Source1");
Object srcAsObject = src; // auto-down-cast to object
また、as()キーワードを使用して明示的にダウンキャストすることも可能です。
src.as(Object).location.x += 2;
FlexScriptがダウンキャストを行う際にノードが対象クラスタイプの有効インスタンスでない場合、無効キャストの例外がスローされます。
Object src = model().find("Tools");// throws invalid cast exception
model().find("Tools").as(Object).location.x += 2; // throws invalid cast exception
ノードがis()キーワードを持つ指定サブクラスタイプなのかを確認できます。
if (model().find("Source1").is(Object)) {
...
}
null値
通常、ツリーノードがnullかを確認するには、単にツリーノードをNULLと比較するか、ツリーノードをifステートメントに直接配置します。キーワードnullvarはnullバリアントを表し、nullツリーノードとは異なります。
treenode fred = model().find("doesnotexist");
return fred == NULL; // true
return fred == nullvar; // false
return tonum(fred); // 0
if (fred) return 1; else return 0; // 0
if (objectexists(fred)) return 1; else return 0; // 0
ただし、いくつかの特殊ケースがあります。
1.旧グローバルコマンドによって返されたツリーノード(例:node())。戻り値はSAFEREFノードになる場合があります。これは有効なメモリアドレスですが、メインまたはビューツリーには存在しません。ツリーノードが有効な参照なのか確認するには、objectexists()を使用する必要があります。例:
treenode fred = node("doesnotexist", model());
return fred == NULL; // false
return fred == nullvar; // false
return tonum(fred); // a non-zero number
if (fred) return 1; else return 0; // 1
if (objectexists(fred)) return 1; else return 0; // 0
2.バリアントに格納されたツリーノード。ツリーノードポインターが0x0を示し、バリアントを返すコマンドまたは動的ラベルアクセスによって返されます。次の例では、Processor1はポインターデータを持つmyPointerLabelというラベルを持っていますが、何も示していません(または0x0を示しています)。
Object processor = model().find("Processor1");
Variant fred = processor.myPointerLabel;
return fred == NULL; // true
return fred == nullvar; // false
return tonum(fred); // 0
if (fred) return 1; else return 0; // 0
if (objectexists(fred)) return 1; else return 0; // 0
3.nullvarであるバリアントで、そのバリアントのタイプが不明な場合です。たとえば、データまたはツリーノードデータの有無が不明なノードの値を読み取る場合です。
treenode Tools = model().find("Tools");
Variant fred = Tools.value;
return fred == NULL; // false
return fred == nullvar; // true
return tonum(fred); // 0
if (fred) return 1; else return 0; // 0
if (objectexists(fred)) return 1; else return 0; // 0
ツリーノードが保持するデータのタイプを確認する場合やツリーノードがデータを一切持っていないかを確認する場合についての詳細は、dataTypeプロパティを参照してください。
プロパティ
dataType | ノードのデータタイプを取得および設定します。 |
first | ノードの最初のサブノードを取得します。 |
labelProperties | 独自の名前付きプロパティを使用して、ラベル値を取得または設定します。 |
labels | ノードのラベルにノードとしてアクセスします。 |
last | ノードの最後のサブノードを取得します。 |
name | ノードの名前を取得および設定します。 |
next | ツリーにあるノードの次のノードを取得します。 |
prev | ツリーにあるノードの前のノードを取得します。 |
rank | 親ノードのサブツリーにあるノードのランクを取得/設定します。 |
subnodes | ノードのサブノードにアクセスします。 |
up | ツリーにあるノードの「上」にあるノード、つまり親ノードを取得/設定します。 |
value | ノード上の値を取得および設定します。 |
メソッド
destroy | ノードを破棄します。 |
evaluate | ノードを評価します。 |
find | ノードのパスによって、ノードのサブツリーにあるノードを検索します。 |
getPath | ノードのパス、必要に応じて他のノードと関連するパスを取得します。 |
詳細
treenode.dataType
int dataType
説明
ノードのデータタイプを取得および設定します。
dataTypeをノードの現在のデータタイプと異なる値に設定した場合、ノードの現在のデータを削除して、新しいデータタイプを追加します。ツリーノードの値を取得および設定するには常にtreenode.valueを使用するだけで十分なため、通常はこのプロパティを使用する必要はありません。
dataTypeで利用可能な値およびマクロは次のとおりです。
None = 0
DATATYPE_NUMBER = 1
DATATYPE_STRING = 2
DATATYPE_COUPLING = 3
DATATYPE_OBJECT = 4
DATATYPE_PARTICLE = 5
DATATYPE_BUNDLE = 6
DATATYPE_SIMPLE = 7
次の例では、文字列データを「MyLabel」というcurrentのラベルに割り当ててそのデータタイプを返しています。
current.labels["MyLabel"].dataType = DATATYPE_STRING;
return current.labels["MyLabel"].dataType;
ノードがデータを持つかどうかは、データタイプをNULLと比較することで確認できます。
node.dataType == NULL
treenode.labelProperties
Variant labelProperties
説明
独自の名前付きプロパティを使用して、ラベル値を取得または設定します。
treenodeクラスを使用して、オブジェクト上のラベルに適用されるカスタム名付きのプロパティを取得および設定できます。たとえば、currentの「MyLabel」という名前のラベルの値を5に設定するには、次のコードを使用します。
current.MyLabel = 5;
これにより、ラベルの値は5に設定されます。その名前のラベルが存在しない場合、オブジェクトのラベルに追加されます。
currentの「MyLabel」ラベルに格納されている値を返すには、次のコードを実行します。
return current.MyLabel;
このラベルアクセスメカニズムは、オブジェクトデータを持つノード、処理フロートークン、Storage.Slot、もしくはタスクシーケンスでのみ利用可能です。これらのタイプではないノードでこのメカニズムを使用する場合、FlexSimは例外をスローします。
動的ラベルプロパティアクセスを使用すると、少し長い式を用いることで可能なことをより短い構文でできるようになります。
短縮構文 | 対応する長い構文 |
---|---|
current.MyLabel | current.labels["MyLabel"].evaluate() |
current.MyLabel = 5 | current.labels.assert("MyLabel").value = 5 * |
* 短縮構文を使用してFlexscriptトグルラベルのコードを設定する場合、コードのFlexScriptも自動構築する点に留意してください。
? 演算子
この演算子と関連する注意事項がいくつかあります。FlexScriptを使用することでノード上の任意のラベル名を取得/設定できるようになるため、ラベルを正しいつづりで記述しなかった場合に潜在的な問題を生じさせます。このため、存在しないラベルを取得した際には、FlexScriptは例外をスローして問題をすぐに指摘します。存在しないラベルに意図的にアクセスしたい場合(存在しない場合は単にnullバリアントまたはnullvarを返します)、ラベル名の後ろに「?」を付けて、未定義ラベルに対して例外をスローしないことを示すことができます。
次のコードを使用すると、「MyLabel」ラベルが存在しない場合に、例外をスローせず単にnullvarを返します。
return current.MyLabel?;
#演算子
オブジェクトがすでにプロパティを持っているため、動的プロパティとして機能しない特定のラベル名があります。例:
current.next = 5;
nextがtreenodeクラスのプロパティであり読み取り専用であるため、例外をスローします。ただし、「next」ラベルを含んでいるオブジェクトを持つことが不可能というわけではありません(たとえば、オブジェクトのプロパティウィンドウを通じてオブジェクトに追加できます)。このラベルには、名前の不一致のない他のラベルと同じ方法で動的プロパティを通じてアクセスすることはできません。動的プロパティを持つこのラベルを参照する(または最初の位置に追加する)ためには、#文字をラベル名の前に追加する必要があります。
current.#next = 5;
オブジェクトの「next」ラベルを正しく検索して、そのnextプロパティは使用しません。
また、ソフトウェア更新時に、モデルのオブジェクトによって使用されるラベル名と一致しないオブジェクトに新規プロパティが追加されます。この場合、コードは自動で更新されて#文字を使用し、それによってコードが同じように動作を続けます。たとえば、オブジェクトの1つで「position」ラベルを使用するとします。
current.position = 5;
次の更新でそのオブジェクトが更新されて新規のpositionプロパティが追加されます。コードは自動で更新されて、次のコードスニペットのようになり、以前と同様に動作を続けます。
current.#position = 5;
treenode.labels
readonly labels
説明
ノードのラベルにノードとしてアクセスします。
このプロパティによって、ラベル値を格納するノードが利用可能になります。通常、labelPropertiesを使用できるため、このプロパティを使用する必要はありません。このルールの例外は次のとおりです。
1.ラベル名にスペースが含まれる- ラベル名にスペースを含める場合、labelsプロパティを使用してそれらにアクセスする必要があります。
current.labels["My Label Name"].value = 5;
このコードはlabelPropertiesを使用する場合よりも煩雑なため、スペースを使用してラベルを名付けないことをお勧めします。
2.ラベルノードに具体的にアクセスしたい - ラベルが値のテーブル場合など、ラベルノードに実際にアクセスしたい場合があります。この場合、labelsプロパティを使用します。Table myTable = current.labels["myTable"];
3.ラベルが存在しない場合にアサートしたい- subnodesプロパティのように、ラベルが存在するようアサートできます。必要に応じて、デフォルト値を渡してラベルを付与できます(存在しない場合)。
// Set myValue to the value of MyLabel
// If MyLabel doesn't exist, create it
Variant myValue = current.labels.assert("MyLabel").value;
// Increment the value of MyLabel by 10
// If MyLabel doesn't exist, create it and set its value to 1
current.labels.assert("MyLabel", 1).value += 10;
treenode.last
readonly treenode last
説明
ノードの最後のサブノードを取得します。
ノードに格納された最終のサブノードへの参照を返します。これによってnode.subnodes[node.subnodes.length]を簡単に使用できるようになりますが、存在しない場合、node.lastは単にNULLを返します。一方で、node.subnodes[node.subnodes.length]は配列範囲外の例外をスローします。
次の例では、currentの最終のサブノード名を「FirstObj」に設定しています。
current.last.name = "FirstObj";
treenode.next
readonly treenode next
説明
ツリーにあるノードの次のノードを取得します。
FlexSimツリーから、同じレベルでこのノードの直後にあるノードを取得します。このノードがそのレベルのツリーにおける最後のノードである場合、このコマンドによってNULLを返し、リクエストされたノードが存在しないことを示します。
次の例では、currentのすべてのアイテムに対して「tally」というラベルを0に設定しています。変数アイテムは、現在動作中のアイテムへの参照を格納するために使用します。
treenode item = current.first;
while (item) {
item.tally = 0;
item = item.next;
}
treenode.prev
readonly treenode prev
説明
ツリーにあるノードの前のノードを取得します。
FlexSimツリーから、同じレベルでこのノードの直前にあるノードを取得します。このノードがそのレベルのツリーにおける最初のノードである場合、このコマンドによってNULLを返し、リクエストされたノードが存在しないことを示します。
次の例では、サブノードを後退方向に走査することで、currentのすべてのアイテムに対して「tally」というラベルを0に設定しています。変数アイテムは、現在動作中のアイテムへの参照を格納するために使用します。
treenode item = current.last;
while (item) {
item.tally = 0;
item = item.prev;
}
treenode.subnodes
readonly subnodes
説明
ノードのサブノードにアクセスします。
サブノード数へのアクセス
次のコードを使用して、currentにおけるサブノード数にアクセスできます。
current.subnodes.length
ランクによるサブノードへのアクセス
次のコードを使用して、個々のサブノードにランクごとにアクセスできます。
current.subnodes[1] // first subnode
current.subnodes[current.subnodes.length] // last subnode
current.subnodes[i] // i-th subnode
名前によるサブノードへのアクセス
次のコードを使用して、個々のサブノードに対して名前ごとにアクセスできます。
current.subnodes["Box1"] // subnode named "Box1"
名前によるサブノードのアサート
次のコードを使用して、サブノードを名前ごとにアサートできます。
// assert a label named "My Label"
current.attrs.labels.subnodes.assert("My Label")
これによって、その名前のノードがすでに存在しているかを確認し、存在していない場合には、その名前を持つサブノードを追加し、結果として得られるサブノードを返します。
デフォルト値を持つサブノードのアサート
また、次のコードを使用して、名前ごとにサブノードをアサートして、デフォルトの開始値を含めることもできます。
// assert a label named "My Label" with a default value of 5
current.attrs.labels.subnodes.assert("My Label", 5)
これは以前のassert()呼び出しと同じですが、ラベルを追加する必要がある場合に値5の追加ラベルを付与する点が異なります。
サブノードの追加
次のコードを使用して、サブノードを追加できます。
// add a new node under current
current.subnodes.add()
currentの下に空のサブノードを追加します。結果として得られるサブノードを返します。
サブノードのクリア
次のコードを使用して、currentのサブノードを削除できます。
current.subnodes.clear();
サブノードの配列を取得
次のコードを使用して、すべてのサブノードの配列を作成できます。
Array subnodes = current.subnodes.toArray();
treenode.value
Variant value
説明
ノード上の値を取得および設定します。
ノードの値を取得する場合、数値データを含むノードは数値を、テキストデータを含むノードはテキストを、そして結合ポインターデータを含むノードは方向を示す目標ノードを返します。配列データを保持するノードは関連付けられた配列を返します。オブジェクトデータを持つノードはノード自身に属性ノードを格納しているため、ノード自身を返します。データを含まないノードはnull バリアントもしくはnullvarを返します。さらに、一部のノードはSimpleDataTypeまたはSDTと呼ばれるカスタムクラスを使用して「カスタム」データを保持する場合があります。これらのタイプでは、カスタムクラスは値がアクセスまたは設定された際に何を返すのかを定義できます。たとえば、追跡変数データを格納するノード(current.attrs.state_currentやcurrent.attrs.stats_contentなど)では、valueプロパティは追跡変数の現在値を返し(getstat(current.attrs.state_current, "", STAT_CURRENT)などと同じ)、値を設定することで追跡変数の現在値を更新します。
例:
currentの3D形状ファイルと関連付けられた形状パスを取得します。
string shapePath = current.attrs.shape.value;
currentの形状インデックスを取得します。
int shapeIndex = current.attrs.shapeindex.value;
currentの「My Label」ラベルの値を5に設定します(なお、ラベル名にスペースを含めない場合は、labelPropertiesを使用することでより簡単に設定できます)。
current.labels["My Label"].value = 5;
currentの「Loading Operator」ラベル(モデルのOperator1を示す)の値をアサートおよび設定します。
current.labels.assert("Loading Operator").value = Model.find("Operator1");
currentの「Loading Operators」ラベルの値を、モデルのオペレーター3個を指し示す配列にアサートおよび設定します。
current.labels.assert("Loading Operators").value =
[Model.find("Operator1"), Model.find("Operator2"), Model.find("Operator3")];
「OperatorName」と名付けられたサブノードをモデルツールフォルダにアサートして、値「Operator1」を付与します。
Model.find("Tools").subnodes.assert("OperatorName").value = "Operator1";
treenode.destroy()
void destroy( ) |
説明
ノードを破棄します。
このメソッドをノードに対して呼び出すと、ノードは破棄されてそれ以降は参照できなくなります。
次の例では、currentのサブノード1つを除いてすべて破棄しています。
while (current.subnodes.length > 1)
current.last.destroy();
treenode.evaluate()
Variant evaluate( ) |
Variant evaluate( Variant p1 ... p20 ) |
パラメータ
p1-p20 | 評価に渡されるパラメータです。これらのパラメータは、param(1)やparam(2)などを使用してノードのコードからアクセスできます。 |
戻り値
Variant | コードトグルの場合、ノードのコード実行結果です。そうでない場合、ノードの値を返します。 |
説明
ノードを評価します。
evaluate()を呼び出し、ノードが数値、非コードテキスト、または配列データを持っている場合、treenode.valueと同じ値を返します。ノードがテキストデータを持ちコード(dll、c++、あるいはFlexScript)としてトグルされた場合、evaluate()はそのコードを実行して結果として得られる値を返します。
treenode.find()
treenode find( string path ) |
パラメータ
path | ノードで開始されて目標ノードに向かうパスです。 |
戻り値
treenode | 指定されたノードが存在する場合、このメソッドはそのノードを返します。それ以外の場合、NULLを返します。 |
説明
ノードのパスによって、ノードのサブツリーにあるノードを検索します。
通常、特有のコマンドが他に存在しないツリー内のノードにアクセスするために、このメソッドを使用します。このコマンドは、unix/windowsファイルパスと同じパス構文を使用します。以下に示すように、ツリーの走査に使用できるパス記号が複数存在します。
/ この記号は、現在のノードのサブツリーに移動するように走査処理に指示します。
> この記号は、オブジェクトの属性ツリーに移動するように走査処理に指示します。
.. この記号は、現在のノードの親ツリー、または1つ上の階層に移動するように走査処理に指示します。
~ この記号は、状況によって2つの意味を持ちます。記号が他の特殊記号(>objectfocus+/~など)の直後にある場合、現在のノードが所有するオブジェクトに移動するように走査処理に指示します。たとえば、現在のノードがオブジェクトの属性ツリー内にある場合、~はオブジェクト自体まで移動します。ただし、記号がノード名の直後にある場合、記号の後に数値があると予想して、指定した名前の「番目」のオブジェクトを定義します。たとえば、MODEL:/Processor~5のパスは、モデル内のProcessorという5番目のオブジェクトを返します。
@ この記号は、現在のノードの所有者ビューに移動するように走査処理に指示します。
+ この記号は、現在のノードのテキストをオブジェクトへのパス(もしくは、ノードがポインターデータを持つ場合はポインターの値)として読み取り、そのオブジェクトに移動するように走査処理に指示します。
" オブジェクト名が特殊パス文字を格納している場合、オブジェクト名を引用符で囲みます。たとえば、パス「MODEL:/"Is Distance > Max Distance?"」は、モデル内で「Is Distance > Max Distance?」という名前のオブジェクトを返します。
? この記号は、続く名前を再帰的に検索するように走査処理に指示します。たとえば、model().find("/?FlowItemBin")と指定すると、FlowItemBinという名前のノードがモデルツリーで検索されます。これにより、明示的なパス定義model().find("/Tools/FlowItemBin")と同じノード参照が返されます。
$ マクロまたはFlexscriptを$文字で囲むことで、ランクまたはノード参照を動的に定義します。たとえば、グローバルマクロMY_RANKを8と定義した場合、パスMODEL:/$MY_RANK$はモデル内のランク8位のオブジェクトを取得します。ここでFlexscriptを定義する場合、iを使用して現在のノードを取得してください。たとえば、パスMODEL:/Processor1/$outobject(i, 3)$は、モデル内のProcessor1というオブジェクトの3番目の出力ポートに接続されるオブジェクトを返します。
多くの場面で「/」および「>」記号のみを使用し、時々「..」記号を使用することになります。通常、「@」および「+」記号はカスタムGUIを構築する際にのみ使用します。
また、名前ではなくランクによってノードを指定することができる機能もあります。通常はオブジェクト名がある箇所に単に数値を入力すると、代わりにランク付けされたノードへアクセスします。
また、パス内にある複数の追加開始点キーワードの1つを、startnodeの代わりとして定義することもできます。これは、パス開始点として定義済みノード(ドット左のノード)よりも優先されます。キーワードは次のとおりです。
MAIN:/ メインプロジェクトツリーで開始します
MODEL:/ モデルツリーで開始します
VIEW:/ ビューツリーで開始します
例1:
treenode curnode = model().find("/Conveyor3/Textured Colored Box");
これは、変数curnodeを「Textured Colored Box」というオブジェクトへの参照として設定します。このオブジェクトはモデル内の「Conveyor3」というオブジェクト内にあります。
例2:
treenode curnode = model().find("/Conveyor3/3");
この例では、curnodeをモデル内の「Conveyor3」というオブジェクトにあるランク3位のオブジェクトに設定しています。この例は、最初の例より優れています。複数のフローアイテムがすべて同じ名前を持つことはよくあります。その場合、パス「/Conveyor3/Textured Colored Box」では、Conveyor3にある「Textured Colored Box」という名前の最初のフローアイテムにしかアクセスできません。Conveyor3に複数のフローアイテムがあり、名前がすべて「Textured Colored Box」の場合、パス「/Conveyor3/2」を使用すればランク2位のフローアイテムを、パス「/Conveyor3/3」を使用すればランク3位のフローアイテム(以降も同様)を取得できます。
例3:
treenode exittriggernode = model().find("/Conveyor3>variables/exittrigger");
この例では、モデル内のConveyor3に対するexittrigger変数をexittriggernodeが参照するように設定しています。最初の例のようにコンベヤのサブツリーに移動する代わりに、「>」記号を使用してコンベヤのオブジェクト属性ツリーに移動するようにしています。オブジェクト属性ツリーはラベル、変数、サイズ、および場所などを保持し、一方でオブジェクトサブツリーはフローアイテムなど他のオブジェクトを保持します。
例4:
treenode focus = c.find("@>objectfocus+");
通常、この例はGUIで使用され、パラメータウィンドウまたはプロパティウィンドウが「指し示す」オブジェクトを利用できるようになります。詳細については、ユーザーマニュアルのグラフィカルユーザーインターフェイスのトピックを参照してください。
treenode.getPath()
string getPath( treenode relativeTo = 0 , int byName = 1 ) |
パラメータ
relativeTo | 定義済みの場合、結果として得られるパスはそのノードに関連したものになります。定義していない場合、パスはグローバルに定義されたパスとなり、MODEL:/などのルートノードプレフィックスを含みます。 |
byName | 定義済みの場合、0は結果として得られるパスがツリーの番号付きランクのシーケンスになることを意味します。1は結果として得られるパスが名前付きノードのシーケンスになることを意味します。 |
戻り値
string | ノードのパスです。 |
説明
ノードのパス、必要に応じて他のノードと関連するパスを取得します。