stateタグの解釈
generalタグの解釈の後に、stateタグの解釈を行います。
このstateタグで記述されている内容が、eSEATの振る舞いを決定しています。
ここの処理では、
- stateタグの''name属性''の値をnameにセット
- ''eSEAT_Core.create_state(name)''を呼び出し、''スロット変数 items[name]=[]''として初期化する。この時''スロット変数 init_state''がNoneであれば、nameをセット
- stateタグの子要素に対して、コマンドやルール、onExecute実行時に呼ばれる処理などの登録
- ''eSEAT_Core.appendState(name)''をコールし、''スロット変数 states''に nameを追加
を行う。
ここでわかることは、eSEATの状態管理に関連するスロット変数は下記のようにまとめられる
スロット変数 | 役割 |
---|---|
states | eSEATに定義されている状態の名前 |
init_state | 最初に定義されている状態名(通常、この状態名が起動時の状態となる) |
items | itemsは、各状態のルール等が記載されている辞書 |
では、次に、上記の 3のstateの子要素の処理について説明していきます。
stateタグは、seatmlのスキーマでは、下記のように定義されています。
<xs:element name="state">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="onentry"/>
<xs:element minOccurs="0" maxOccurs="1" ref="onexit"/>
<xs:element minOccurs="0" maxOccurs="1" ref="onexec"/>
<xs:element minOccurs="0" maxOccurs="1" ref="ontimeout"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element minOccurs="0" maxOccurs="unbounded" ref="rule"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="label"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="button"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="input"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="text"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="brk"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="space"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
すなわち、stateの子要素として、onentry, onexit, onexec が0または1つ、rule,label,button,input,text,brk,spaceのタグが0個以上記載することができます。
したがって、それぞれの子要素に応じて、内部で処理を行っています。
onentry, onexitタグの処理
onentryタブとonexitタグは、eSEATの状態遷移が起こった場合に、該当する状態に遷移する直前に行う処理と該当する状態から遷移する前に行う初期を定義する場合にそれぞれ使用します。
この部分の処理は、
commands = self.parseCommands(e)
self.parent.registerCommands(name+":::"+e.tag , commands)
と記載されており、onentryまたはonexitの要素のコマンドを 'name:::onentry'または 'name:::onexit'というキーでスロット変数 keys に割り当てます。
''parseCommands''メソッドの処理に関しては、generalタグの解釈の部分を参照してください。
onexecタグの処理
onexecタグの処理は、generalタグの解釈の部分とほぼ同じです。
内部では、''parseExec''メソッドを実行しており、子要素のコマンド列を 'name::onexec'というキーでスロット変数 keys に割り当てます。
generalタグの解釈の場合と異なるのは、generalタグの部分は全状態に共通の振舞いであり、ここで定義する部分は、状態の応じて変更される部分になります。
ontimeoutタグの処理
ontimeoutタグの処理は、generalタグの解釈の部分とほぼ同じです。
内部では、''parseTimeout''メソッドを実行しており、子要素のコマンド列を 'name::ontimeout'というキーでスロット変数 keys に割り当てます。
generalタグの解釈の場合と異なるのは、generalタグの部分は全状態に共通の振舞いであり、ここで定義する部分は、状態の応じて変更される部分になります。generalタグとstateタグの両方でontimeoutが設定された場合には、stateタグで設定した方のみが有効になります。
ruleタグの処理
ruleタグは、現在の状態における入力に応じた振舞いを規定している部分になります。外部からの入力に応じたeSEATの振舞いは、このruleタグのみで定義していることになります。
ruleタグは、seatmlファイルのスキーマでは、下記のように定義されています。
<xs:element name="rule">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="cond"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element minOccurs="0" maxOccurs="unbounded" ref="key"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="message"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="command"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="shell"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="script"/>
<xs:element minOccurs="0" maxOccurs="1" ref="statetransition"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="log"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="source" use="optional" type="xs:string"/>
<xs:attribute name="file" use="optional" type="xs:string"/>
</xs:complexType>
</xs:element>
では、ruleタグの処理を順に追っていきます。ruleタグの処理は、''parseRule''メソッドをコールしています。
まず、最初にruleタグの ''file属性''の有無を調べます。file属性が与えられた場合には、外部のseatmlファイル内の同じ状態名または指定した状態名のruleタグをすべてインポートします。(内部では、''loadRuleFule''メソッドがコールされます)
例えば、外部ファイルsample.seatml内に定義されている state1のruleタグをすべてインポートしたい場合には、
<rule file="sample.seatml:state1" />
という記述を行います。file属性が定義された場合には、要素にコマンド列が記載されていても無視されることに気を付けたください。
次に、''file属性''が指定されなかった場合には、要素のコマンド列の処理を行います。上記のseatmlのスキーマにありますが、ruleタグ内には、''parseCommands''メソッドの処理の対象となる message, command, shell, script, statetransition, logの他に key, condというタグが記載可能です。
ここでの処理は、
- ''parseCommands''メソッドをコールして、コマンド列をcommandsという内部変数にセット
- ''source属性''の値を adaptor内部変数にセット、 ''keyタグ''を keys内部変数にセット
- adaptorに値があった場合
- keysがあれば、各keyタグの要素について''decompString関数''で文字列を分解し、各文字列 wについて、'name:adaptor:w'というキーでスロット変数 keysにcommandsを割り当てる
- ''condタグ''があれば kond内部変数に [ <execfile属性値>, <condタグの要素> ]をセットし、そうでなければ [None, "True" ]をセット
- 'name:adaptor:ondata'というキーでスロット変数 keysに[kond, commands]を割り当てる
- adaptorに値がなかった場合
- 各keyタグの要素について''source属性''があれば、source内部変数にその属性値をセットし、そうでなければ'default'をセット
- 各keyタグの要素について''decompString関数''で文字列を分解し、各文字列 wについて、'name:source:w'というキーでスロット変数 keysにcommandsを割り当て
となっています。
その他(GUI部品)
上記以外のタグ(label, button, input, text, brk, spsce)は、GUIを作成するためのタグであり、''parseGui''メソッドを実行しています。parseGuiメソッドでは、タグ名に応じたGui部品をパネルに張り付けGUIを生成します。
各タグの要素は、、''parseCommands''メソッドで処理を行い、コマンド列を生成し、各Gui部品のアクションに関連付けを行っています。