C++でコルーチン

yuki
記事: 5
登録日時: 14年前

C++でコルーチン

投稿記事 by yuki » 14年前

何とか実装する手立てを考えましたが、やはりアセンブラを使うしかなさそうです。
setjmp/longjmpを使っても中のアドレスがエンコードされていたりするので、
アセンブラでレジスタの中身を持ってくるしかなさそうでした。
(setjmp/longjmpで実装できるのは、ギリギリ例外処理までかな?)

一応switchと__LINE__を利用したコルーチンもどきは作れますが、
中でswitch文が使えない、マクロを使う、ローカル変数のアクセスが面倒くさいなど、
色々問題というか面倒ごとが多いのです。

アセンブラを使うって言っても、理屈上ではレジスタの中身を書き換えるだけなので、
環境に依存するようなコードもほとんど無いはず。
(メモリの方向くらいは調べたほうが良いかな)
機能も、resumeとyieldだけで、引数無しであれば簡単かな。
ということで、今度の休みに色々と実験してみたいなと思います。

しかし、ゲームで凄く役立つのに有名なライブラリがPCLだけっていうのも悲しいこと(有名といってもマイナーな部類)。
スクリプト言語のLuaがコルーチンを実装していたりもするのですが、
C++で直にコルーチンを書きたいっていう場面もありますよね。
最後に編集したユーザー yuki on 2011年2月19日(土) 03:35 [ 編集 1 回目 ]

アバター
へろりくしょん
記事: 92
登録日時: 14年前

Re: C++でコルーチン

投稿記事 by へろりくしょん » 14年前

素直にマルチスレッドで実装すればいいんじゃないですか?
まぁ、ちょっと面倒ですけど。

それはそうと、コルーチンってなんだか可愛らしい語感ですよね。 コルー・チンって感じです。
ひらがなにすると、こるぅちんです。 いや、なんだか、ホント可愛いですね。

yuki
記事: 5
登録日時: 14年前

Re: C++でコルーチン

投稿記事 by yuki » 14年前

コメントありがとうございます(^^
そうなんです。素直にマルチスレッドで実装する手もあったんですけど、
小さな仕事を一つさせるのにスタックを大量に消費するのもいただけないと思いました。
(潤沢な今の環境にはそぐわない精神ですが)

コルーチンって可愛いですよね。
他にもファイバーとかマイクロスレッドとかいう呼び方ありますけど、
可愛いのでコルーチンという呼び方を愛用してます(^^
私はCoroutineのCoro派です(?)

ISLe
記事: 2650
登録日時: 14年前

Re: C++でコルーチン

投稿記事 by ISLe » 14年前

コルーチンは自発的にリターンするわけでスレッドの代わりにはならないですよね。
ゲームプログラムでコルーチンが役に立つのってどんなところなんでしょう。

iアプリであっちこっちにメインループがあるプログラムをBREWに移植したときはコルーチンが使えたら楽だったと思います。
コルーチンもどきで対応しましたけど。
マルチスレッドが自由に使えない環境で需要が高いのではないでしょうか。

yuki
記事: 5
登録日時: 14年前

Re: C++でコルーチン

投稿記事 by yuki » 14年前

>ISLeさん
コメントありがとうございます(^^

ゲームで役立つ部分といえば、AIが最たるものでしょうか。
STGで言えば敵の挙動や、RPGで言えば会話やイベントなど。
有限状態機械なオブジェクトは、コルーチンで制御すると楽だなぁと思います。

マルチスレッドが自由に使えない環境といえば、Windows3.1なんかは
マルチタスクの実装にコルーチンみたいなものが使われてましたね。

ISLe
記事: 2650
登録日時: 14年前

Re: C++でコルーチン

投稿記事 by ISLe » 14年前

yuki さんが書きました:ゲームで役立つ部分といえば、AIが最たるものでしょうか。
STGで言えば敵の挙動や、RPGで言えば会話やイベントなど。
有限状態機械なオブジェクトは、コルーチンで制御すると楽だなぁと思います。
描画フレームの枠を超えて時間の掛かる処理はインタープリタで実装するとCPU時間を無駄にしないで済みます。
それはいわゆるスクリプトというものであるだけで十分ですよね。

STGの敵の挙動やRPGの会話やイベントは描画タイミングで同期を取らなければいけません。
同期を意識したコードを書くとなるとコルーチンにはステートパターンではなく閉じたループで書けるというメリットしかない気がします。
例えばゲームキャラをひとつずつスレッドにしたら同期制御でむしろ手に負えないくらいたいへんなことになるのですが、それと同じようなことにはならないでしょうかね。
あと、個人的には経験上、閉じたループでコードを書けることはメリットよりもデメリットが大きいと感じています。

とは言えスペック的にそうとう恵まれた環境でなければコルーチン自体を使えないので個人的にはまだまだ関係ない世界ですが。

yuki
記事: 5
登録日時: 14年前

RE: C++でコルーチン

投稿記事 by yuki » 14年前

CODE:

void Test1()
{
	static int count = 0;
	
	if(count <= 30)
	{
		// 待つだけ
	}
	else if(count <= 60)
	{
		// 1
	}
	else if(count <= 140)
	{
		// 2
	}
	else
	{
		count = 0;
	}
	
	++count;
}

void Test2(Coroutine &c)
{
	for(;;)
	{
		c.wait(30);
		// 待つだけ
		
		for(int i = 0; i < 30; ++i)
		{
			// 1
			c.yield();
		}
		
		for(int i = 0; i < 80; ++i)
		{
			// 2
			c.yield();
		}
	}
}
Test1をTest2みたいに書ければ楽だと思ったのですが、デメリットのほうが多いんですね(--;
あまり経験豊富ではないので興味本位なのが正直ですが、もう少し色々と試したいと思います。