Apricotと状態遷移

次のバージョンのデスクトップマスコット「Apricot 3.9」から、新しく導入する機能「状態遷移」について書いてみました。

Apricot 3.9から導入する状態遷移を用いると、キャラクターをある条件下のもと動作を変えるといったことが可能になります。

通常、このような条件分岐には、さまざまな言語に見られるifのような条件文を使うのが一般的です。
しかし、条件文を導入すると実装のコストの増加とキャラクターを定義するXMLも複雑になります。

そこで、これらの問題を解決するために「状態遷移」を導入します。状態遷移は条件分岐を、低い実装コストで今と同じようなXMLの構造で行えるようにします。もちろん、「状態遷移」と「条件分岐」は等価ではありませんが、デスクトップマスコットでは十分な機能であると考えてます。

ちなみに、この「状態遷移」とはオートマトンで述べられる状態遷移と同じようなものです。というか、アイディアはオートマトンから拝借しています。

なので基本的な動作は、まずキャラクターを定義してあるXMLに含まれるsequenceタグの「状態」を遷移させます。すると、ある「状態」下では呼ばれるsequenceタグを作り出すことが出来ます。このようなある「状態」下でのみに呼ばれるsequenceをつくることで、条件分岐のような制御をすることが出来ます。

さて、実際にXMLを見ていくと、sequenceタグのstate属性が上の状態と呼ばれるものにあたります。
状態を変化させるにはcallタグで、変化させたいsequenceタグの名前(sequenceタグのname属性の値)を指定し、状態を表す文字列をstate属性に設定します。
尚、状態の有効範囲はsequenceタグの名前毎です。また、sequenceタグのstate属性はcallタグのstate属性の値を正規表現でチェックします。つまり、sequenceタグのstate属性に正規表現が使用でき、状態の文字列に対して正規表現でマッチしたsequenceが実行されます。

<sequence name="Activate">
  <call name="Activate" state="S1">
</sequence>
<sequence name="Activate" state="S1">
  <message>Foo</message>
</sequence>
<sequence name="Activate" state="S1">
  <message>Bar</message>
</sequence>
<sequence name="Activate" state="S2">
  <message>Foo</message>
</sequence>

具体的な流れとしては、上の例の一番上のActivateが呼ばれると、状態は「S1」に移り、state属性の値が「S1」にマッチするsequenceタグが実行されます。
上の例では、状態「S1」でマッチするsequenceは2つあり、どちらかが実行されることになります。そして、状態「S1」なので、sequenceタグの属性値が「S2」のものは実行されることはありません。
また、状態「S1」でstate属性を設定せずにcallタグを用いると、自動的に現在の状態のsequenceタグが呼び出されることになります。(つまり、例では「S1」)

このように、sequenceタグのname属性とstate属性、callタグのname属性とstate属性を使うことで状態遷移を行うことが出来るようになります。


参考:

オートマトン - Wikipedia
http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%88%E3%83%B3