コルーチンの原理
いや、
「コルーチンはこう書けばいいよ!」
って言われても、なんでこれで動くのかイマイチわからないと使いづらくない?
そういうわけで、このページではIEnumeratorとかIEnumerableが何者なのか、なぜ動くのかについて解説します。
ちなみに両方UnityじゃなくてC#の機能です。
IEnumerableとはなんぞや(Unityのコルーチン書くのに不要なので飛ばしてOK)
>IEnumerable は、列挙可能なすべての非ジェネリックコレクションの基本インターフェイスです。 このインターフェイスのジェネリックバ ージョンについては、「System.Collections.Generic.IEnumerable<T>」を参照してください。 IEnumerable には、IEnumeratorを返す1つのメソッド GetEnumeratorが含まれています。 IEnumerator は、Current のプロパティと MoveNext および Reset メソッドを公開することによって、コレクションを反復処理する機能を提供します。
ホアーッッッ!!!!!!!(発狂死)
大事なところを抜き出しますと、
>IEnumerable には、IEnumeratorを返す1つのメソッド GetEnumeratorが含まれています。
つまりこれはIEnumeratorをnewして返してくれる。製造装置に過ぎない。
それで、IEnumeratorって結局なんなのよ?
IEnumeratorとはなんぞや
>IEnumerator は、すべての非ジェネリック列挙子の基本インターフェイスです。
???????????????????????
そう、実はこいつコルーチン用のインターフェイスではなく、ほぼforeach用に作られたインターフェイスだったのである。
必須な機能についていろいろ書かれているが、配列と違って等差数列など処理が都度必要な配列とかがかける。
配列だと、配列にあらかじめ入っているやつを順に読んでいくことしかできないが、こいつは
「次の要素何?」
って聞かれてから処理して
「えーと、〇〇っした!」
というノリで書ける。
上にも挙げた例でいくと
foreachくん「1,5,9の処理は終わった……次何で処理回せばいい?」
IEnumeratorくん「えっと……さっきのが9だったから4足して……13っす!」
としてる。
でもそんなことは意識して書くことはない。
これはイテレーター構文というので書くと勝手にこの仕組みをC#くんが作ってくれるから。
それがyield returnを使う構文だったりする。
つまり、
IEnumerator<int> Hoge()
{
int num = -3
while(true)
yield return num+=4;
}
とかけばよい。
なんでこれでコルーチンになるの?
さて、こう聞くとまるでyield returnが主役みたいだが、コルーチンはこれを悪用した。
つまり、
Unityくん「コルーチンくん元気?」
IEnumeratorくん「(やべっ、次の処理しなきゃ……)カタカタ……はい!元気です!」
と、returnするまでに行われる処理のほうでコルーチン処理を行うことにしたのだ。
ここで、Unityくんにどう返事するかは処理に全く関係なくてもよいからだ。
この場合のコードはこんな感じになる。
IEnumerator Hoge()
{
while(true)
//なんかすごい処理
yield return null;
}
Unityくん視点では「null」という返事をもらうためにIEnumeratorを呼び出しているわけだ。
で、IEnumerator視点では、「null」という返事を返すまでに内職のようにやりたいことをしている。
ここで、nullの代わりにwaitForSeconds()とかを返せば、Unityくんはそれを受け取って呼び出すタイミングを変える。
さて、どうだろう?
あ、間違えた