Sonntag の VEventBus について
Sonntag は設計上、画面のレイアウトを担当するGraphic、処理の内容を担当するCommand、そしてその間を取り持つScreenの3つの役割がそれぞれ分担されることによって、疎結合を実現しています。
この方式を採用することで、各業務(画面)ごとに開発が行えるだけでなく、デザインとロジックを切り分けることで、依存性を低く保ち、たとえば画面デザイナーと処理記述のプログラマーが分散して開発を進めることができるようになっています。
各業務画面(Graphic)をユーザーが操作し、発生する処理は、Commandの中に記述し、bind-screen-command や Screen.do-command などを利用して間接的に呼び出すようになっています。
また、ある画面から、別の画面の処理を呼び出したい、という場合には、「イベントバス」という概念を利用します。
このイベントバスには、インスタンス化されたすべてのScreenが関連付けられており、あるScreenがこのイベントバスにメッセージを送ると、関連付けられているすべてのScreenにそのメッセージがブロードキャストされます。
具体的には、メッセージを送るScreen の send-message メソッドを呼び出してメッセージを送信します。
そのメッセージは、各Screen の handle-message メソッドに送られるので、受け側のScreenはそのメソッドをオーバーライドすることで、メッセージを受け取ることができます。
メッセージとして送信できるのは、 any型の任意の値(またはオブジェクト)です。
他のScreenにデータを渡す必要がある場合は、そのデータをもつオブジェクトをメッセージとして送信することができます。
また、このsend-message のイベントは非同期で実行されますが、send-message-syncを利用することで、メッセージを送った後のイベントが実行し終えるまで同期して待つことが可能です。
この同期方式を利用し、受け側のScreenの処理の中で送られてきたメッセージの中にデータを格納し、処理が終了した後、同期された送り側のScreenがそのデータを参照することで、間接的に戻り値のようにしてデータを受け取ることも可能です。
■EventBus を利用したサンプル
イベントバスを利用するサンプルを作成しましたので参考にして下さい。
Sonntag EventBusサンプル http://developers.curlap.com/curl/Sontag-event-bus.zip
サンプルでは、あるScreen (親画面)の中に「クリア」ボタンと、タブコンテナが含まれ、そのタブコンテナの2つのペインが、それぞれ別のScreenを含んでいます。
コンテナペインの中のScreenは、テキストフィールドをひとつずつ含んでいます。
親画面の「クリア」ボタンを押すと、各コンテナの中のテキストフィールドの値がクリアされるという処理を、イベントバスを利用して実装しています。
親画面の「クリア」ボタンを押すと、send-message メソッドが呼ばれ、”clear” というメッセージがイベントバスに送られます。
イベントバスは、タブコンテナの中のScreenにメッセージをブロードキャストして届け、そのhandle-event の中でテキストフィールドをクリアするCommandを呼び出しています。