コルーチンの実装についてメモ。
【動作】
普通の関数(サブルーチン)はこうなる。
1.関数を呼び出す
2.関数が実行される
3.関数から呼び出し元に戻ってくる
コルーチンだとこうなる。
1.コルーチンを呼び出す
2.コルーチンを実行する
3.コルーチン内で中断されるか最後まで実行されると呼び出し元に戻る
4.中断された場合は、そのコルーチンをもう一度呼びだすと、中断された場所から実行できる
3と4はとても重要。
【理屈】
理屈は簡単。
普通の関数は、今あるスタックの上に戻り値と引数を積んで関数をcallし、戻るときに全て破棄していたのを、
コルーチンでは中断するときに、スタックとレジスタの中身を保存し、呼び出し元に戻れば良い。
もう一度そのコルーチンを呼び出すときは、保存しておいたスタックとレジスタを格納して呼び出せばOK
【実装】
レジスタを保存/格納するだけならば、setjmp/longjmpでもできるのだけど、スタックが保存/格納出来なければ意味が無い(不正なスタックのねじ曲げとなる)。
呼び出し先から呼び出し元にlongjmpするときはスタックをpopするだけだが、呼び出し元から呼び出し先にlongjmpすると、あったはずのスタックが無いことになる(呼び出し元に戻る時点で破棄される)ので不正。
なので、インライン(でなくてもいい)アセンブラでレジスタと一緒にスタックの中身を保存するルーチンを作る必要がある。
あと、関数とその状態を結びつけるので、構造体なりクラスなりを使う必要がある。
【速度】
中断/再開するたびにスタックの中身を移す処理をするのは遅いかもしれない。
【必要性】
普通のプログラムでは、まず要らない。
ただ、ゲームとなると話は違う。
AIや状態遷移などは、コルーチンがあると便利。
正直難しいのはレジスタとスタックの格納/保存だけなので、アセンブラの練習と思って実装してみるのも悪くないかも。
とまで書いたけど、switch文使ってC/C++の言語レベルで紛い物位は作れます。
【メモ】コルーチン
Re: 【メモ】コルーチン
コメントありがとうございます。
普通のプログラムだと完全に不必要ですが、
ゲームであれば例えばAIだったり、状態管理だったりが楽になりますよ。
敵キャラクタの動きの制御や、イベントの自動再生だとか。
現在のマルチスレッドの布石にもなってるので、実装の面では勉強にはなりますよ。
C#のはイテレータを簡単実装させるための仕組みとか謳ってますけど、どうみてもコルーチン用ですよね(^^;
普通のプログラムだと完全に不必要ですが、
ゲームであれば例えばAIだったり、状態管理だったりが楽になりますよ。
敵キャラクタの動きの制御や、イベントの自動再生だとか。
現在のマルチスレッドの布石にもなってるので、実装の面では勉強にはなりますよ。
C#のはイテレータを簡単実装させるための仕組みとか謳ってますけど、どうみてもコルーチン用ですよね(^^;