web-dev-qa-db-ja.com

ステートマシンとGUI間の通信

ライブラリとして設計されたC++で有限状態マシンを書いています。さらに、ライブラリで発生する状態の変化に応じてユーザーインターフェイスを更新する必要がある別のプロジェクトとして実装されたGUIがあります。

ここで通信を実装する方法は、GUIがライブラリ関数を呼び出し、有限状態マシンの状態に関する情報(およびその他の必要な情報)を含む構造体を返すことです。

しかし、これはかなりアドホックな解決策であると私は思います。それは頻繁な状況のように思われるので、これを処理するデザインパターン/テキストブックの方法があるかどうか知りたいです。

4
user695652

最も簡単な方法は、状態が変化した(または他のイベントが発生した)ときに呼び出されるコールバック関数を状態マシンに渡すことです。

次に、それが呼び出されたときに、その関数のGUIを更新できます(または、状態マシンが別のスレッドで実行されている場合は、メッセージをGUIスレッドに転送します)。

署名はvoid callback(State oldstate, State newstate, void* userData)のようなものになります

userDataポインターは、関数ポインターと同時に提供され、(静的)コールバック関数のコンテキストを提供します。必要に応じて、std::Function代わりに、関数pointer + userDataメソッドをオーバーロードとして保持します。

5
ratchet freak

GUIライブラリ(Qtなど)は、イベントベースのサブスクライバーパブリッシャーデザインパターンを使用しています。つまり、イベントでは、すべてのサブスクライバーに通知されます。

したがって、状態が変化したら、イベントを公開します。イベントをサブスクライブしたすべてのオブジェクトは、コールバックを実行します。

2
BЈовић

Observerパターンは、GUIを更新するためのシンプルでクリーンなソリューションだと思います。

これは、システムのようなイベントを実装できるようにする動作パターンです。これにより、GUIがライブラリから適切に切り離されます。

私は通常、他のアダプターパターンと組み合わせて使用​​して、メインのエンティティから具体的な「更新」実装を分離します。このようにして、IObserverから継承することなく、さまざまな更新動作を混合して一致させることができます

https://en.wikipedia.org/?title=Observer_pattern

「コールバック」実装よりも優れている点は次のとおりです。

  • 通知を受ける複数のオブザーバーがいて、それぞれが異なる方法で応答することが可能です
  • 操作を開始したクラスは、反応するクラスとは異なる場合があるため、モデル-ビュー-コントローラーパラダイムを実装します。
  • イベントごとに異なるリストを実装して、オブザーバーが何を反応させるかを選択することもできます

たとえば、それを使用してGUIを更新したり、ファイルやその他のログに記録したりすることができます。これらはすべて個別のスレッドで行われます。

2
eviloop