サイログ。

~雑多な記事置き場~

Miyako meets Fiber

なんか、某巨大掲示板で、ウチの日記絡みでFiberの話が出てるらしいので補足です。

手前味噌ですが、Miyako2.0に、Fiberの利用例がありますので、参考にして頂けると嬉しいです。
Miyako2.0では、Yukiクラス(Miyakoで使用するシナリオエンジンクラス)を実装するために使っています。

以前は、Yukiは独立したスクリプト言語でしたが、後にDSLのように扱える様にMiyakoの中に取り込んでしまいました。しかし、Yukiの処理の中で「待ち」が出てくると、メイン処理に戻れない問題がありました。
2.0まではThread使って対処していた時もありましたが、Fiberの存在を知り、使いやすいと考えたため、Ruby1.9.1専用にしてFiberを導入しました。

Yuki内部では、以下の4つの場面で、メイン処理とYukiの処理とで切り替えが必要になります。

  1. 文字の表示(Yuki#textメソッド。文字列を渡しているが、実際は1文字ずつ表示してメイン処理に戻って同期的に処理を行う)
  2. ポーズ処理(Yuki#pauseメソッド。アドベンチャーRPGによくある「ボタンを押すまでカーソル出して待つ」アレ。待ってる間にメイン処理に戻って(略)。キー入力はメイン処理に一任のため、「キーを押した」状態を伝える必要がある)
  3. コマンド選択時(Yuki#commandメソッド。そのまんまですね。「キーを押したらカーソル動かしてボタンを押したら決定」のアレ。選択中にメイン処(略))
  4. ウェイト処理(Yuki#waitメソッド。「x秒間待って」のアレ。待ってる間にメイ(略))

Miyako2.0では、Yukiクラスインスタンスの中にFiberクラスインスタンスが一つ入っています。
Fiberで評価するブロックは、中にYukiスクリプトが入っているFacadeパターンのブロックです。
(Fiberでは、「始まる前」と「終わった後」が分からない(スクリプト実行中か分からない)ため、スクリプト実行の前後にフラグを設定しています)

実際に、Fiber#resumeを呼んでいるのは以下の2つのメソッドです。
これらのメソッドを呼ぶことで、Yukiスクリプトの実行に移っています。

Yuki#start_plot メソッド(Yukiスクリプトの実行開始)
Yuki#update メソッド(Yukiスクリプト処理の更新)

処理がFiberに移った後、Yuki#text、Yuki#pause、Yuki#command、Yuki#waitの各メソッドでは、フラグをトリガーにしたwhileブロック内でFiber.yieldが呼び出され、再びメイン処理に戻ります。

こうすることで、メイン処理とYukiスクリプトの実行を切り分けて行えます。

もし、何かご不明な事がございましたら、質問よろしくお願い致します。

github内に、Windows上のRuby1.9.1で使えるRuby/SDL+Miyako2.0のバイナリを置いています。
zip/tar.gzでのダウンロードが可能です(「download」ボタンを押してみて下さい)
http://github.com/cyross/miyako2_with_ruby_sdl_win32_binary/tree/master
↓が、Ruby1.9.1のmswin32バイナリがダウンロードできるリンク(artonさんのとこ)です。
http://arton.no-ip.info/data/asr/