あなたは論理を複雑にしすぎていると思います。私はそれを単純化しすぎているかもしれません...:)
すべての文法を1つのファイルに含めることができます。最初のコマンドをリッスンするときに、フォローアップをリッスンするフラグをコードに設定します。
これが(簡略化された)文法セットです:
<grammar version="1.0" xml:lang="en-US" root="rootRule" tag-format="semantics/1.0" xmlns="http://www.w3.org/2001/06/grammar">
<rule id="rootRule">
<one-of>
<item>
<tag>out.SysCommand = "STATUS";</tag>
Computer what is the system status
</item>
<item>
<tag>out.SysCommand = "PASSWORD";</tag>
Gamma
<one-of>
<item>Four</item>
<item>Forty</item>
</one-of>
Seven Echo
</item>
</one-of>
</root>
</grammar>
コールバックは次のようになります。
private void OnSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Confidence >= ConfidenceThreshold)
{
if (IsListening)
{
if (e.Result.Semantics["SysCommand"] != null)
{
switch (e.Result.Semantics["SysCommand"].Value.ToString())
{
case "PASSWORD":
// The was waiting for this, now you can act on it
break;
default:
// something else was said, reset!
break;
}
}
}
else if (e.Result.Semantics["SysCommand"] != null)
{
if (e.Result.Semantics["SysCommand"].Value.ToString() == "STATUS")
{
// do stuff that prompts user for password
IsListening = true;
}
}
}
}
コールバックは「IsListening」フラグを探します。設定されていない場合は、ステータスを要求したかどうかを確認します。実行した場合は、フラグが設定され、パスワードを待機します。
上記のコードを合理化できます。私はそれをコピーして、私が行ったのと同じようなものからいくつかの簡単な編集を行いました。私の場合、次のことを行います。
- システムの名前を聞きます(「フロイド」)
- 「IsListening」フラグを設定する
- 可能なフォローアップコマンドを示すプロンプトを画面に表示します(可視性はIsListeningフラグにバインドされています)。
- それらのコマンドを聞いて、適切に行動してください
必要に応じて新しい文法をロードおよびアンロードできますが、文法ファイルが大きくならない限り、それらのロード/アンロードのオーバーヘッドは、単一のセットでいくつかの追加の文法ルールを調べるだけですぐに追いつき始めます。