タスクシステム総合スレ part2
at GAMEDEV
[1からを表示]
50:名前は開発中のものです。
07/12/10 16:08:36 FhEMVCWa
>>48
さてはDirect3D使ったこと無いな?
51:名前は開発中のものです。
07/12/10 17:15:59 TRJA29h8
>>48
見た感じ
・タイトル画面
・戦闘画面
・マップ移動画面
みたいなのをシーンと書いてあるだけ。
>>50
なぜ突然Direct3D・・・
(IDirect3DDeviceN::BeginScene?)
52:名前は開発中のものです。
07/12/10 18:15:58 kVa9UCh4
定義厨の俺でも
さすがに>>48はないな
53:名前は開発中のものです。
07/12/10 19:32:53 ynLW352R
ゲームをまともに作れないことが明らかな>>48の発言に、一同、シーンとなった。
54:名前は開発中のものです。
07/12/10 19:44:32 sWUDY/qD
プログラム開発現場の駄洒落は99%、発言者が死ねばいいのにという感想になる。
しかもバグの取れない苛立ちまでも一手に引き受けてな。
55:名前は開発中のものです。
07/12/11 00:04:17 T0+r8UQD
>>53
誰がシーンとなることを言えと
56:名前は開発中のものです。
07/12/11 00:53:40 ECQVp0Tr
さっきからチーンチーンチーンチーンってお前等は変態か?
57:名前は開発中のものです。
07/12/11 08:56:37 xDs0NYc0
ユビキタスとかWeb2.0とかあんな感じの電波を感じるな
58:名前は開発中のものです。
07/12/15 22:33:07 dW/LIK6y
>>44
説明しよう!
>コールバック=何かをきっかけに呼び出される
まさにその通りだ!!
コールバック関数とは関数ポインタを呼び出し側に登録しておき
適宜呼び出される方式だ
この方式はタスクシステムにも採用されている
タスクヘッダには初期値としてタスクエンド(Cでは大抵NULLだろう)を示すポインタが入っている
図1.タスクヘッダ → タスクエンド
ここにタスクを登録していくことで呼び出される関数が増えていく
図2.タスクヘッド → タスク1 → タスク2 → タスクエンド
こうして生成されたタスクリストのタスクはタスクループで順番に呼び出されていく
図3.タスクループ
↓
タスクヘッド → タスク1 → タスク2 → タスクエンド
以上のような構造からタスクシステムはコールバック関数であるといえる
コールバック関数に比べてタスクシステムを特徴づけているのは次の3点だ
1.呼び出し側と呼び出され側が1対多である
2.呼び出し側は機能を持たない
3.呼び出され側がさらに呼び出され側を登録することができる
以上の特徴により、動的に機能を拡張し、相互に連携することが可能になったのである
59:名前は開発中のものです。
07/12/16 00:14:11 tU3FXTu1
>>58
> 以上の特徴により、動的に機能を拡張し、相互に連携することが可能になったのである
単にインスタンスの数が可変なだけで、連携については何も触れてないじゃん。
60:名前は開発中のものです。
07/12/16 01:22:25 Uds4tbII
先頭をheadにするなら末尾はtailにしてくれ
末尾をendにするなら先頭はbeginかstartにしてくれ
俺が言いたいのはそれだけ
61:名前は開発中のものです。
07/12/16 01:27:07 tU3FXTu1
>>58
どうでも良いけど
> タスクヘッダには初期値としてタスクエンド(Cでは大抵NULLだろう)を示すポインタが入っている
番兵1つ置いた方が、余計な場合分けが減って嬉しくない?
BSDで使われてる TAILQ でも、ヘッドは
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
っつー定義だよな。
あと C++ だと昔は std::list<> 好きだったが、最近は std::vector で、フレームの最後に
まとめて std::remove_if と std::vector<>::erase 組み合わせて済ませる方向に。
62:名前は開発中のものです。
07/12/16 01:50:58 eEobSst5
>>58
タスクシステムが誕生する70年代末期よりも遥か前の
古典的なコンピュータのプログラムで既に同じようなことをやってるだろ。
例えば、割り込み信号にフックするとき、つまり割り込み処理ルーチン
(常駐プログラム・サービス)を割り込みベクタテーブルに追加するとき
既存のルーチンがあればそれと数珠繋ぎにするだろ
63:名前は開発中のものです。
07/12/16 02:16:17 eEobSst5
単純で乱暴なやり方をするなら、割り込みベクタテーブルに
既存ルーチンの代わりに自分のアドレスを上書きして
先に自分の処理を呼び出させ、自分の処理が終わったら
既存ルーチンへジャンプさせる。つまり割り込み処理に割り込む。
もう少し紳士的なやり方なら(同じ割り込み信号にフックする)
割り込み処理ルーチン同士で協定を作り
割り込み処理ルーチンのリストを管理するルーチンを用意する。
こうした仕組みは>>58の言う
1.呼び出し側と呼び出され側が1対多である
2.呼び出し側は機能を持たない
3.呼び出され側がさらに呼び出され側を登録することができる
を全て満たしている。
呼び出し側=ハードウェア
呼び出され側=割り込み処理ルーチン
ハードウェアは割り込み信号に応じて割り込みベクタテーブルの
当該アドレスに登録されてる割り込み処理ルーチンを呼び出す。
そしてリストに登録された順に次々呼び出される。
割り込み処理ルーチンは処理完了時のリターン命令を
他のルーチンへのジャンプ命令に書き換えることで
子ルーチンの追加が可能
64:名前は開発中のものです。
07/12/16 02:18:07 eEobSst5
紳士的なやり方なら
呼び出し側=割り込み処理ルーチンのリスト管理プログラム、か
65:名前は開発中のものです。
07/12/17 15:54:34 d05xYvvB
意見は出したくないが文句はつけたい
そんな嫌タスク厨の巣窟だというのがわかる流れでしたね
文句つけてる暇があったら、58がかすむくらいの有益情報でも書き込めっての
66:名前は開発中のものです。
07/12/17 16:25:30 fh4AIKkl
またブーメラン芸か
67:名前は開発中のものです。
07/12/17 16:43:25 fh4AIKkl
=210.130.51.98 ヘ( `Д)ノ
68:名前は開発中のものです。
07/12/17 21:14:21 PVpDrrvq
コールバック進化系(笑)スィーツ(笑)
69:名前は開発中のものです。
07/12/17 21:26:04 FK63IV8y
確かにプログラム用語の大半はスイーツ(笑)テイストを感じさせる回りくどい言い回しだな
70:名前は開発中のものです。
07/12/17 23:00:26 ZuWNJ+Fe
つまりタスクシステムは何なわけ?
わたしわかりまぁせん
71:名前は開発中のものです。
07/12/17 23:12:00 DxnpSp/c
foreach
72:名前は開発中のものです。
07/12/17 23:52:08 lVhxy2mV
ここはwhile(1);つかfor(;;);かな。最適化されてればどっちも同じだろうが。
73:名前は開発中のものです。
07/12/18 20:23:42 RgUcH/0L
1フレーム毎に(大抵)全てのオブジェクトのupdateメソッドがコールバックされるシステム
と考えていいんじゃね?
74:名前は開発中のものです。
07/12/18 23:42:42 LovnfmvP
-----------------------------------------------------------
987 :名前は開発中のものです。:2007/12/03(月) 23:02:28 ID:hqsjjSWF
スレのログ見ると、定期的に「タスクシステム=デザインパターン」とか絶叫してる人がいるみたいだが
この人たちの言うタスクシステムってどのタスクシステムの話なんだろうね?
【1.タスクシステム=Logician Lordで紹介されているもののことだよ】
ギャラクシアンとその直系に見られる特徴的な実装こそタスクシステムであり
その要件を満たさない異形のコードは全て紛い物だ。タスクシステムとか名乗るな
【2.タスクシステム=リスト巡回UPDATE。ていうかforeachだよ。】
ギャラクシアンのそれとは全く別物の、異形のコードであろうとも
俺がタスクシステムって呼べばタスクシステムなんだいバーロー
-----------------------------------------------------------
観察してると、どうもタスク厨って呼ばれてる子は後者が多いような気がしてきた。
何も知らない頭白紙の状態で松浦教祖に洗礼を受けたこの恐るべき子供たちは
タスクシステムというフレーズにとても執着してるようだが、厨房神経を刺激する
何かがあるのか?
とにかく何が何でもこのタスクシステムという古のローカル用語を俺様理論で
再定義・再構築してやろう、という無駄な努力がヒシヒシと伝わってくるんだが
ある意味で(マムコ信者に言わせれば)由緒正しいwローカル用語をわざわざ
掘り起こしてきて流用するのは止めてくれって思う
「朕思うに」「新概念」「新解釈」「オナニー」「再構築」は好きなだけやっていいから
なんか別の名前にしろよ。「リスト巡回UPDATE」でも「僕のforeach」でも
「エターナルフォースブリザードシステム」でも何でもいいからさ
75:名前は開発中のものです。
07/12/18 23:44:17 m+PO2WK4
私はもうタスクという言葉自体を使ってない
76:名前は開発中のものです。
07/12/19 08:00:04 hUc1dbeP
ゲイは身をタスク。
77:名前は開発中のものです。
07/12/19 15:24:26 Ir64JLrB
○○システムって言い方自体、かなり厨2魂を揺さぶるフレーズだよ
78:名前は開発中のものです。
07/12/19 15:25:28 F/n53iWq
じゃあタスクパターンで
79:名前は開発中のものです。
07/12/19 20:46:55 UEhDeB5F
>タスクパターン
「ストラテジーパターン?あー、AoEとか大戦略ってパターンだよね」
とか真顔で言ってのけるウィザード級ハッカーの心の琴線に触れる
80:名前は開発中のものです。
07/12/19 20:47:44 hUc1dbeP
じゃあ、「タスクモンスターとのアルティメットコラボレーション」で。
81:名前は開発中のものです。
07/12/20 07:20:27 c5xOqVc7
>>74
タスクシスステム改め
ギャラクシアンロジックかLogician Load Systemでおk
82:名前は開発中のものです。
07/12/20 20:44:20 tLt8cR7R
エロスロジック
83:名前は開発中のものです。
07/12/21 00:29:57 rVMYRhvV
オナニーシステムで通じると思うんだ
リスト巡回オナニーも分かりやすい
オナニーforeachは微妙
オナニーパターンはオナテク板で使用済み
84:名前は開発中のものです。
07/12/21 00:38:40 Jo2a6K/I
じゃ、タスクシステム関連は、PinkBBSに移動しようか。
85:名前は開発中のものです。
07/12/21 01:45:05 sZQMdwXf
僕の肛門もリスト巡回されそうです
86:名前は開発中のものです。
07/12/31 11:54:08 K8WL7pln
どうすればギャラクシアンのソースを見られますか?
87:名前は開発中のものです。
07/12/31 15:03:05 73X1rpDN
逆アセンブルすればそれがほぼソース
88:名前は開発中のものです。
07/12/31 18:29:38 K8WL7pln
>>87
ファミコン版でいいですか?
89:名前は開発中のものです。
08/01/07 06:40:49 5ateSYSb
タスクシステムこそ
ゲーム業界にのみ伝わる現代の魔術
連綿と口伝によってのみ受け継がれ
変化し、進化と退化を繰り返す
その亜流は数知れず、もはやその全てを語れるものはいない
90:名前は開発中のものです。
08/01/07 14:38:53 GyFmGIbt
都市伝説テンプレート
91:名前は開発中のものです。
08/01/14 14:54:45 qTpR8IwF
つまりはスケジューリングでおk?
92:名前は開発中のものです。
08/01/14 15:24:10 qReoD61a
少なくともスケジューリングは含まれるだろうな
93:名前は開発中のものです。
08/03/13 22:58:00 Bu/r75Um
保守
94:名前は開発中のものです。
08/04/03 17:01:08 0WE0DNgq
ゲームプログラミングで分厚い目の本選んだら
著者流タスクシステムの解説が大半で(´・ω・`) ショボーン。
95:名前は開発中のものです。
08/04/03 18:08:34 HifUC8Yv
>>94
>>7
96:名前は開発中のものです。
08/04/03 18:34:18 0WE0DNgq
逆引きタスクシステム
これだorz
97:名前は開発中のものです。
08/04/03 18:37:31 0WE0DNgq
ちょっと違ったな。
買ったのは「逆引きゲームプログラミング」って書いてあるから姉妹本かな。
表紙に堂々とタスクシステムなんて書いてあったらさすがにスルーするしねw
98:名前は開発中のものです。
08/04/06 18:50:02 cIcTAloV
Javaはポインタが使えないからイテレータ使うしかないのかな?
99:名前は開発中のものです。
08/04/06 21:07:19 RBp65Y5g
>>98
Java がポインタを使えないのは確かだが、たぶん >>98 はそれ以前の
勘違いをしている。
100:名前は開発中のものです。
08/04/06 21:09:30 ptmozDNb
ねぇぼく、すれたいよめゆ?
101:名前は開発中のものです。
08/04/06 21:24:10 hAyEqcH5
>>98にタスク厨の素質を感じた
お前たち、大事に育てなさい
102:名前は開発中のものです。
08/04/07 04:08:41 qDynBUHm
■星屑きらら杯
URLリンク(kirara111.sakura.ne.jp)
主催:111
超絶神星屑きららを迎えての史上最強コンテスト。
優勝賞金はwebマネー3万円ぶん。
今までの常識は通用しない、コードネームは・・・アンタッチャブル。
103:名前は開発中のものです。
08/04/07 16:38:25 V2Suu5FZ
ほえ
104:名前は開発中のものです。
08/04/20 10:58:52 tFc51Cra
boost::circular_bufferってタスクシステム向きだと思う
105:名前は開発中のものです。
08/04/21 20:44:13 RVUuTgSY
どこらへんが向いてると思うの?
バッファからあふれた分は上書きされるわけだが・・・
106:名前は開発中のものです。
08/05/05 11:03:20 RRXW9Hmv
結局タスクシステムって良いプログラム??それとも悪いプログラム??
107:名前は開発中のものです。
08/05/05 16:01:08 h5LjEvcu
普通のプログラム
このボケを期待してたんだろうけど若い人はこのネタ知らないよ。
欽どんと欽どこのどっちだったかな。
108:名前は開発中のものです。
08/05/05 16:01:33 /b4BEf3P
適材適所
なんでもタスクシステムで済まそうとすると苦労する
109:名前は開発中のものです。
08/05/05 18:20:31 mspxDfm7
この絵は良い絵ですか?悪い絵ですか?
110:名前は開発中のものです。
08/05/23 05:11:37 urjZe250
もーやだ
普通に逐次処理で書いて並列的な仕事はスレッドっぽい何かでやりたい
ゴリゴリとタスクとやらで状態マシン書いていけるお前らはすげーよ
俺は頭悪いから無理。forループ相当のことやるだけでも混乱する
111:名前は開発中のものです。
08/05/24 21:14:24 MJp3dmaD
>>110
普通に考えてスレッド同士の関連の処理考えるだけで頭痛いじゃん
分けたからどうだってのよ?
結局
主人公:スレッドNo1
敵A:スレッドNo2
障害物A:スレッドNo3
ってなったら、例えスレッドに分けたとしても
関連時にスレッドNo1xスレッドNo2xスレッドNo3のステータス分の
対応表ができることはかわらんがな
言ってることわかる?
つまり、スレッドごとにステータスが3つ(仮に状態○、△、□とする)あったら
敵A○ 敵A△ 敵A□
主人公○ STA STB STC
主人公△ STC STC STA
主人公□ X X X
敵A○ 敵A△ 敵A□
障害物○ STA STB STC
障害物△ STC STC STA
障害物□ X X X
主人公x障害物省略
STA ステータスA
STB ステータスB
X なにもおきない
とか必要になるってわかるだろ?
112:名前は開発中のものです。
08/05/25 00:58:28 6V9YbMCv
>>111
タスクシステムとやらを使っても
全部処理しなければならないというのは一緒なんだろ
ならどっちでもいいじゃないか、状態遷移の話をしているのか?
113:名前は開発中のものです。
08/05/25 01:06:31 6V9YbMCv
スレッド使えばこんな感じに書けるはずだが
主人公() {
while (true) {
if (A) ... ;
else if (B) ... ;
else if (C) ... ;
}
yield();
}
タスクシステムとやらを使ったときのありえない複雑さは凡人の俺には理解できない
簡単にできるものをわざわざ複雑に書く、天才だけの思考は全く理解できんな
114:名前は開発中のものです。
08/05/25 05:25:51 dDrBARgy
>>111が何を言いたいのかはよくわからんが、
タスクシステムも>>113も、複雑さは特に変わらないように思えるけど。
class 主人公 : public Task {
void 実行() {
if (A) ... ;
else if (B) ... ;
else if (C) ... ;
}
};
どの辺が、>>113に比べて「ありえない複雑さ」なんだ?
115:名前は開発中のものです。
08/05/25 05:35:43 5unbeWfm
サブクラスにいちいちIF仕込んでんのかよw
116:名前は開発中のものです。
08/05/25 08:15:02 vQVRM4Hf
>>110ですが、俺は>>112-113とは別人です一応
まあ使ってんだけどねタスク。仕事だし
>>111の言うような連携処理は、処理自体の複雑さの問題だと思うんだわ
俺が言ってんのはもっと低レベルな話でー
//10フレームかけて10ドット右へ
for (int i=0; i<10; ++i) {
move_right(1);
}
とやればいいとこが、
//10フレームかけて10ドット右へ
void task_handler() {
static int i = 0;
if (i >= 10) {
go_next_mode(); // 処理が終わったよ!
return;
}
move_right(1);
}
みたいになるのが長いと言うか分かりづらいと言うか、処理がこみいってくると混乱するなあと。
俺、なんか勘違いしてますかねー?
117:名前は開発中のものです。
08/05/25 08:40:06 vQVRM4Hf
ごめん、ちょっと直した。あとインデント入れた
//10フレームかけて10ドット右へ
for (int i=0; i<10; ++i) {
yield();
move_right(1);
}
//10フレームかけて10ドット右へ
void task_handler() {
static int i = 0;
if (i++ >= 10) {
go_next_mode(); // 処理が終わったよ!
return;
}
move_right(1);
}
118:名前は開発中のものです。
08/05/25 09:38:01 xbxgumKd
>>117
前者の方が不自然に感じる俺はどうすれば・・・
119:名前は開発中のものです。
08/05/25 10:39:48 qUO2NAd9
>>113
スレッドの生成/破棄がどれだけ高コストか分かっているのかね?
>>117
途中のフレームでやっぱり左に切り返す処理等を入れたら後者の方が
遥かにシンプルになる。
120:名前は開発中のものです。
08/05/25 10:52:41 7UG2hamH
>>112
いや、だから変わらんでしょ?って言いたかったわけよ
121:名前は開発中のものです。
08/05/25 10:57:13 7UG2hamH
あーだから、スレッドなんて作っても
根本の複雑さが問題なんであってタスクシステムなんて
してもここは変わらんよと
122:名前は開発中のものです。
08/05/25 11:08:35 K3dp7DqQ
時間かけて行う処理、広くいうと、ある条件を満たすまで待って次に進むような逐次処理
を書こうとすると>>117の言うようなストレートに記述をしたくなるのは分かる
こういうのをコルーチン(co-routine)っていうんだっけ。
ただ>>119の後半にあるように条件判断をイテレーションごとに行う必要があるなら、
コルーチンであってもコルーチンっぽくは見えなくなってしまうかもしれない
(スレタイにあわせていうなら)
たとえば制御系タスクとワーカ系タスクっていうのがあって、
それぞれ記述しやすい方法が違ったりする?
制御系タスク イテレーション(表示フレーム?)ごとに細かい条件判定を行い、大きな分岐がある
ワーカ系タスク ↑に比べて単純なループ、条件判定は脱出するかどうか、程度
おれなら、
前者はメッセージディスパッチャっぽく書きたい。
後者はコルーチンっぽく書きたい。
なあ。
123:名前は開発中のものです。
08/05/25 11:56:53 MyJQpRZH
結局何やっても複雑になるんだからどんな実装してもおk
Flashなんかも標準でタスクシステム(笑)のような仕組み持ってるんだけど、
やっぱ処理順序とかインタラクトとかみんな悩んでるお
124:名前は開発中のものです。
08/05/25 14:13:14 7UG2hamH
作るもん間違ってんじゃねぇの?
>>117みたいな処理ってスクリプトやプログラムで解決しないで
フラッシュみたいなタイムライン(?)があるビジュアル的なもんがあったほうがいいんじゃねぇの?
んでキャラの状態遷移みたいなもんは遷移図と各ステータスの遷移条件表がないとどうしたってダメだろ?
こんな属性の違うもんをいっぺんに解決しようとする手段を探してること自体
問題の切り分けができていないんと違うか?
タスクシステムはあくまで全然別な独立処理をわかりやすく書くためだけのもんだろ
こいつは上記の2つの問題にはなんの解決策にもなっていねぇ
ゲームプログラムが複雑なのはオブジェクト同士の絡みだろ?
125:名前は開発中のものです。
08/05/25 14:17:00 vQVRM4Hf
>>119
あ、そうなのか? あー、そうかも。
>>122
なる。制御系とワーク系って分けると、なんか分かりやすい。
多分俺がストレスを感じるのは、ちょっとした演出、タイトル画面のデモ、プレイ前の説明画面、
そういう目立たないけど手早くたくさん作らないとならない動きをつけるために、
ゲーム時のキャラクター制御と同じくらいがっちり組まされることなんだな。
実際、ゲーム中の制御は最初からがっちり組みにいくんでストレス感じないし、
俺の場合はイベントドリブンで考えた方が組みやすいから確かに>>119の言う通りかも知れない。
しかし・・・だまされないぞ!
イベントドリブンがしたければ別にスレッドでもできるわけで(Windowsで言うPeekMessageね)、
スレッドのコストの問題は(色々と解決方法が考えられるはずなので)ここでは無視して考えてほしいんだけど、
処理によってはタスクと同じ機構をスレッド上に構築することがあったとしても、
それが可能なことは悪いことじゃないと思わない?
それはC++がベターCとして使えるように、スレッドがベタータスクとして使えることだとは思わない?
126:名前は開発中のものです。
08/05/25 15:41:32 0NNJH3W1
>>122
コルーチンとかファイバーとか言うね。
少し違うけど継続(continuation)の方が知られてるかな。
スレッドは同時に走ることを期待するからこの点は違う。
そういやゲーム方面でLuaが人気あるらしいけど
コルーチンも使ってるのかな。
127:名前は開発中のものです。
08/05/25 15:43:46 dDrBARgy
我々に必要なスレッドは2つ。
メインスレッド、データ読み込みスレッド、BGM再生スレッド、この3つだ。
スクリプトでタイトル画面実装してコルーチン使う、とかならともかく、
キャラの制御なんかと同じレベルにスレッドぽこぽこ作るのは嫌だなぁ。
つか、どう実装するにしても、
ボタンによる演出スキップとか、時間経過によるデモへの移行とか、
タイトル画面程度のものでも状態遷移は考えなきゃならないと思うけど。
まあ、キャラなんかとは、複雑さは全然違うけどさ。
128:名前は開発中のものです。
08/05/25 15:55:46 7UG2hamH
何度も言うけどスレッドは状態遷移の複雑さの問題を解決しないよ
129:名前は開発中のものです。
08/05/25 16:03:27 zNY0acjC
マトリクスでも書いて整理しろよ
130:名前は開発中のものです。
08/05/25 16:43:17 vQVRM4Hf
全レスしたいけどウザがられるしとりあえず
>>128
んとですね、夢を語ってるように見えたかも知れないけどもw
スレッドがゲームの状態遷移の複雑さを解決すると考えているのではなく、
タイマードリブンないわゆるタスク処理というものは、
本来ローカル変数やプログラムカウンタという言語上の機能を
プログラマが自分で状態として(ワーク変数などで)管理しなくてはならないのが
負担だと思いませんかと言いたいのです
131:名前は開発中のものです。
08/05/25 17:01:19 vQVRM4Hf
あ、俺が想定してるスレッドは擬似スレッドです。コルーチン等
OSが用意するプロセス/タスク/スレッドは想定してないです
132:名前は開発中のものです。
08/05/25 17:02:07 7UG2hamH
>>130
もとのレスと比べて全然いってることが違うような希ガス
133:名前は開発中のものです。
08/05/25 17:02:23 6V9YbMCv
おれも>>130と同じ事が聞きたい
話を広げて逃げないでください>天才タスカーの皆さん
134:名前は開発中のものです。
08/05/25 17:15:50 7UG2hamH
>>133
んあ?
考えてることがさっぱりわからん
ゲームプログラムで複雑なのは各オブジェクトの状態遷移であって
タスクシステム云々は問題じゃねぇから気に入った方法で好きにしろってのが
みんなの総意だろ(おそらく)
ここまででなんか違うこと言ってるならなんか言ってみ?
135:名前は開発中のものです。
08/05/25 17:22:31 6V9YbMCv
>>134
130に対する答えにはなってないな
質問の意味が理解できないのならできるだけわかりやすく解説するが、必要か?
136:名前は開発中のものです。
08/05/25 17:23:16 A+/TQh+q
>あ、俺が想定してるスレッドは擬似スレッドです。コルーチン等
最初から「マイクロスレッド」と言えば無用な混乱を避けられるぞ
137:名前は開発中のものです。
08/05/25 17:23:43 vQVRM4Hf
>>134
ですよねー
すんません、でかけてきます
138:名前は開発中のものです。
08/05/25 18:00:32 xbxgumKd
ゲームプログラムからそれを取ったら後は何が残るんだ?
139:名前は開発中のものです。
08/05/25 18:10:01 dDrBARgy
>>113 の if の羅列は状態ごとの処理の振り分けじゃなかったのか。
140:名前は開発中のものです。
08/05/25 18:24:49 6V9YbMCv
>>139
状態ごとの処理の振り分けが何を指すのかわからないけど
マイクロスレッドと状態遷移のトレードオフとして
例えば信号の状態が「赤、青、黄」の三つだとして
普通に状態遷移を書く場合(Stateパターンではなく)
state; // をメンバ変数か、グローバルで
if (state == 赤) ... ;
else if (state == 青) ... ;
else if (state == 黄) ... ;
それよりも、スレッドを用いて
while (true)
{
赤(); sleep(?);
黄(); sleep(?);
青(); sleep(?);
}
の方が直感的で読みやすいでしょという意味で書いたつもり。
141:名前は開発中のものです。
08/05/25 18:38:09 A+/TQh+q
青→黄→赤と遷移するんだろう?
さっそくバグを仕込んでいるじゃないか
142:名前は開発中のものです。
08/05/25 18:52:00 6V9YbMCv
GOFパターンで言うと
タスクシステムとやらがStateのCommandをListに突っ込んだものなら
Stateのメリットは拡張性にあって可読性にはないから
可読性を優先するならマイクロスレッドの形を取るべきだ
と言いたいわけだ。
ところが天才タスカーはタスクシステムを使えば簡単になるよとしか言わない
可読性が低下するというデメリットにも触れない、又は理解していない
そう見える
143:名前は開発中のものです。
08/05/25 19:34:28 dDrBARgy
>>140
? ごめん。>>113 をどう読んでも、そうは解釈できんわ。
……まあ、>>140として、
それだと、他から状態を変えたりしにくいし、
仕様変更への対応も大変じゃないか?
仕様が確定していて絶対変わらないというのならいいけど。
>>142
「簡単になる」とは誰も言ってないよ。
そもそも「すべての場合でタスクシステムを使え」とも言ってない。
(実装方法そのものが本質ではないから)状態遷移の複雑さに応じて、
自分のやりやすい方法でやれと、みんな言ってると思うんだが。
何か変な思い込みが議論を阻害してる気がするな。
144:名前は開発中のものです。
08/05/25 19:57:43 7UG2hamH
>>140
上はstateによって処理を決定するけど下はなんだ?
stateを途中で変えられないような気がすんだけど
なんか比べるもん間違ってね?
145:名前は開発中のものです。
08/05/25 22:16:46 6V9YbMCv
142に書いてる
>Stateのメリットは拡張性にあって可読性にはないから
>可読性を優先するならマイクロスレッドの形を取るべきだ
マイクロスレッドの方が可読性が高いかどうかは主観によるものだが
これを否定するのなら、そっちに話を持っていく
可変性や拡張性が低いってのも142に書いてるけど
そもそもスレッドを与えるクラスが小さいものであるなら、変更は脅威ではない
逆に、タスクシステムとやらが変更に強いとも断定はできない
あれは新しいクラスを作る拡張に強いのであって、置き換える形の変更には強いが
修正する変更はスレッドを用いたものと同じようなものだ
146:名前は開発中のものです。
08/05/25 22:45:40 dDrBARgy
たとえば、>>140 の信号に「夜間は点滅する」「殴られたら停止する」という仕様が追加された場合、
前者の、普通に状態遷移を書く場合だと、
void 夜になる() { if (state != 停止) state = 点滅; }
void 朝になる() { if (state == 点滅) state = 赤; }
void 殴る() { state = 停止; }
みたいなメソッドを追加して、
if (state == 赤) ... ;
else if (state == 青) ... ;
else if (state == 黄) ... ;
else if (state == 点滅) ... ;
else if (state == 停止) ... ;
と分岐を追加していけばいいよね。
後者のスレッドを用いる場合だとどう修正するの?
結局、似たような感じになっていく気がするんだけど。
147:名前は開発中のものです。
08/05/25 23:08:03 jMUik1Ya
>>125
>イベントドリブンがしたければ別にスレッドでもできるわけで
スレッドとタスクシステム(笑)では想定されている粒度が違う
極端な話、相互作用ありのパーティクルにスレッドなんて使わない
たとえばコンテキストスイッチなんて御大層なサービス要らないでしょ
148:名前は開発中のものです。
08/05/25 23:16:28 jMUik1Ya
>>131
えー。それは疑似タスク(笑)同様に疑似スレッド(笑)でしょ
単語の使い方が変杉。最初からスレッドでなく俺定義の
スレッド(笑)の話ってことを断ってその定義も説明しといてよ
149:名前は開発中のものです。
08/05/25 23:21:39 7UG2hamH
>>148
まあ、それはわかってるからいちいちこだわんなよ
わかってないのお前ぐらいだってw
150:名前は開発中のものです。
08/05/25 23:25:47 jMUik1Ya
携帯端末でテケトーに流し読みレスしてっから
会話の全体像は見えてないよ!俺は!
151:名前は開発中のものです。
08/05/25 23:27:07 6V9YbMCv
>>146
がんがん追加してください
追加するほどスレッドを使った方がいいじゃないかと思えてきます
Stateを用いると文の上下の意味的なつながりがなくなるため
規模が大きくなるほどコードが分散して理解するのが困難になります
while (true)
{
if (通常)
{
赤(); sleep(?);
青(); sleep(?);
黄(); sleep(?);
}
else // 真夜中
{
点滅(); sleep(?);
}
}
void 緊急停止()
{
スレッドに対して停止命令();
}
152:名前は開発中のものです。
08/05/25 23:27:28 4NW3nz0D
てかくだんね
153:名前は開発中のものです。
08/05/25 23:29:42 jMUik1Ya
そもそもタスク(笑)とマイクロスレッドの明白な相違点て何よ
例えばコンテキストスイッチ付いてるとタスク(笑)じゃないっていうなら
おまいらのいうタスク(笑)ってどういうタスク(笑)なの
Logician Lordのタスクか?
154:名前は開発中のものです。
08/05/25 23:59:22 vQVRM4Hf
俺の考えなしな書き込みのせいで、
タスクとコルーチンが対立項として扱われてる感じで、なんかゴメン
今までの流れから自分がどっちに行きたいのか整理してみると、こんな感じ
・タスク(あるいはオブジェクト指向による代替タスク)は有用だ。それはもちろん
・ただし、イベントドリブン主体であることには欠点もある。>>130のような負担ね
・コルーチンを併用すればそれを補えるかも知れない
例えばもし次のような実装が手元にあって、簡単にイベントドリブンとコルーチンを
使い分けられるなら、早く仕事がこなせる方をケースバイケースで選びたいよね
class Task {
public:
//サブクラスでonFrameTimer()をインプリメントすると毎フレームコールバック処理が行えます
virtual void onFrameTimer() {}
//サブクラスでcoroMain()をインプリメントすると関数がコルーチンとして起動されます
//yield()でメインルーチンへ処理が戻り、次フレームで再開(resume)、を繰り返します
virtual void coroMain() {}
}
実際にこんなC++実装が手元にあれば、みんな使う?
>>151氏あたりは既に使ってそうだけど、俺は使わない、もしくは迷うと思う。
実行コンテキスト切り替えコードは大抵アセンブリで速いけど移植性がないし、
他人に引き継ぎしずらいし(普及してないから)、ノウハウが無ければケアレスミスで簡単にスタックあふれるし。
だけどオールドスタイルのタスクもとてもストレスがたまるんだ
じゃあどうしたい、どうしたらいい、って話を、俺と同じように
現状のタスクに(意識的、または無意識的に)ストレス感じてる人に聞いてみたかったんだ
155:名前は開発中のものです。
08/05/26 00:21:41 UvsW7CAY
タスク(笑)といえばイベントドリブンなのか?
一定のタイムスライスでコンテキストスイッチするものはもはやタスク(笑)ではないのか?
156:名前は開発中のものです。
08/05/26 00:39:42 J4tqU4Kx
>>151
>がんがん追加してください
じゃあ、もう少し追加してみる。
「殴られたら停止する」を、「殴られたら青→黄→赤の遷移を強制的にひとつ進める」に修正。
「点滅状態からの復帰時、点滅状態に遷移する直前の状態に戻す」を追加。
class 信号 {
enum State { 赤, 青, 黄, 点滅 };
State state, oldState;
void 実行() {
switch (state) {
case 赤: 赤処理(); break;
case 青: 青処理(); break;
case 黄: 黄処理(); break;
case 点滅: 点滅処理(); break;
}
}
void 殴る() {
if (state == 赤) state = 青;
else if (state == 青) state = 黄;
else if (state == 黄) state = 赤;
}
void 夜になる() { oldState = state; state = 点滅; }
void 朝になる() { state = oldState; }
};
>Stateを用いると文の上下の意味的なつながりがなくなるため
>規模が大きくなるほどコードが分散して理解するのが困難になります
ところで、この部分が何を言ってるのか良く分からないんだけど、もう少し説明してくれない?
関数が長くなるから読みにくくなるってことじゃないよね?
>>154
前にも書いたけど、そういうのは同じレベルで実装しないで、
コルーチンを使いたい部分をスクリプトで実装するのが良いと思う。
157:名前は開発中のものです。
08/05/26 00:56:08 FFo0It8G
あんたらいちいち相手を挑発しなきゃ議論できねーのかw
158:名前は開発中のものです。
08/05/26 01:19:18 lNPZHMUK
>>156
ひどいやつだなw
Pythonのジェネレータ関数風味で
色 foo() {
while (true) {
yield 赤;
if (夜) {
yield 点滅;
yield 赤;
}
yield 青;
if (夜) {
yield 点滅;
yield 青;
}
yield 黄;
if (夜) {
yield 点滅;
yield 黄;
}
}
}
void 殴る() { foo(); }
処理の前後に何が処理されているのかというのは
スレッドなら前後の文を見ればすむ。
stateで管理するとstateの変化を追って確認しなければならないから
前後の流れを読むのが難しい。
gotoのスパゲッティコードのデメリットと同じようなもの。
分けてすぎたせいで、逆に可読性が失われている。
159:名前は開発中のものです。
08/05/26 01:25:20 onffbclF
coroutine的なことやってるのはスクリプト上だから移植うんぬんの悩みはないな
かといってオールマイティなのかといえばそーでもなく
時間経過に連続的に対応するような流れのもんは、要するにsleepをする必要のないものは
逆にcoroutineしないほうがきれい
>>156のように二通り選べるようにするのは理想的なのかもしれないが
大体ある特定の現象群を表現する分にはどっちか片方で十分だったりする
160:名前は開発中のものです。
08/05/26 01:37:09 lNPZHMUK
>>159
>時間経過に連続的に対応するような流れのもんは、要するにsleepをする必要のないものは
>逆にcoroutineしないほうがきれい
無理やりタスクシステムとやらのメリットを作ろうとしても無駄
タスクシステムとやら、つまりStateのメリットは拡張性にある
そのため可読性をかなり犠牲にしている
普通に書けばcoroutineの方が可読性が高い場合が多い、俺の主観では
161:名前は開発中のものです。
08/05/26 02:05:33 02TzkeDh
>>154
少し前の俺を見ているようだ。
>>116,130はコルーチンを使えば時系列に沿った行動の記述が簡単になる、という主張でいいんだよな?
それを踏まえるが、時系列に沿った記述をするコルーチン内では
外的要因による状態遷移を行おうとすると複雑になる、というのは気づいているかな。
yield() する前に毎回状態をチェックしてもいいんだが、チェックする内容によっては
スタックが溢れかねないし。
タスクで状態を監視&管理しながら、コルーチンなりスクリプトなりで記述された行動を呼び出して、
両方の良いとこ取りをするのがいいと思うな。外的要因による行動の差し替えはタスクから行う、と。
俺はそうしてるよ。
162:名前は開発中のものです。
08/05/26 02:29:45 J4tqU4Kx
>>158
夜間に殴りつづけたときの動作がおかしくない?
>stateで管理するとstateの変化を追って確認しなければならないから
>前後の流れを読むのが難しい。
そういう面は確かにある。けど、通常の流れはstateを順番に
見ていけばいいので、それほど複雑にはならないと思うし、
特殊な処理を通常の流れとは分けて書けるメリットがある。
>>158みたいなやり方だと、一部分を見たときに前後の流れは直線的に理解できるけど、
通常の流れ(この場合だと夜=falseの場合)が読みにくくならないか?
163:名前は開発中のものです。
08/05/26 02:33:43 lNPZHMUK
タスクシステムとやらを使うメリットを誰も言えない
でも、タスクシステム信者としては黙ってられない
目を覚ませ
高いレベルでCommand利用を前提としたロジックを実装すると
他の有益なパターンが使いづらくなる
わざわざ、自分で制限をかけてプログラムを書いて
なんの修行をしているんだってのw
164:名前は開発中のものです。
08/05/26 02:51:26 lNPZHMUK
>>162
君こそ通常時の遷移が抜けてるぜw
状態遷移図書いたらわかるけど、このケースだと状態が
赤、黄、青、赤点滅、黄点滅、青点滅の六つ必要になってる
俺は状態遷移そのものが複雑なだけと見てるから
その割には単純になったと思ってる
どっちを選択しても複雑なんだから
StateをCommandとしてListに突っ込んでさらに複雑にするのは
バカげていると思わないかい?
165:名前は開発中のものです。
08/05/26 03:18:22 j2qTftQO
どーでもいいじゃん
166:名前は開発中のものです。
08/05/26 03:53:53 J4tqU4Kx
あー、ごめん。「点滅」は色とは関係ないつもりだった。実際は黄色か赤だろうけど。
つまり、State は4つで、夜間は殴ってもなにも起きなくていい。
つか、自分で仕様変更して自分でソース書いてるんだから、
「状態の数が違う」みたいな豪快なバグは入れないよ。
でも、状態が6つだとしても、>>158 はおかしいだろ。
夜間に殴りつづけると、点滅→赤→青→点滅……と変わっていくんじゃないの?
通常時の遷移はわざわざ書く必要もないだろうし、改行が多すぎて拒否されたんで省いたけど、
その部分だけ書くと、こんな感じかな。
class 信号 {
static const int 赤時間;
static const int 黄時間;
static const int 青時間;
int timer;
void SetState(State state) { this->state = state; timer = 0; }
void 赤処理() { if (++timer >= 赤時間) SetState(青); }
void 黄処理() { if (++timer >= 黄時間) SetState(赤); }
void 青処理() { if (++timer >= 青時間) SetState(黄); }
};
>StateをCommandとしてListに突っ込んで
というのが分からんのだが、List に突っ込むのは
タスク (この場合は信号オブジェクト) であって、State じゃないだろ。
状態ごとの処理は各タスク内で完結してるんだから、さらに複雑にはならんよ。
167:名前は開発中のものです。
08/05/26 05:18:08 lNPZHMUK
>>166
俺の書き方が悪かった、二択だ
ひとつめ
赤、青、黄、赤の裏の点滅、青の裏の点滅、黄の裏の点滅
ふたつめ
赤、青、黄、点滅
このどちらかが状態のリストになる
コードは前者であると仮定してシンプルに書いた、点滅は書き損じ
それとも、状態遷移の状態も作るというのなら、俺はパス
168:名前は開発中のものです。
08/05/26 05:33:57 lNPZHMUK
赤、青、黄、赤の裏の点滅、青の裏の点滅、黄の裏の点滅
ならば
遷移が発生するイベントは時間経過(通常)と殴ると時間経過(例外)
赤、青、黄、点滅
ならば
遷移が発生するイベントは時間経過(通常)と殴ると時間経過(例外)
さらに、時間経過(例外)から入力された三つの値、赤から、青から、黄からのイベント
時間経過(例外時)に入力が発生する
169:名前は開発中のものです。
08/05/26 12:34:03 J4tqU4Kx
よくわからん。「状態遷移の状態」を作るってどういう意味?
あと、普通に色が変わる場合の「時間」は誰がどこで設定するの?
他のオブジェクトから信号の色を知りたい場合にどうするのかも気になる。
結局、>>158 のスクリプトとは別のところで信号の状態を管理することになるんじゃないの?
170:名前は開発中のものです。
08/05/26 15:51:02 lNPZHMUK
状態のネストというらしい、俺はその辺は詳しくない
最初に適当に書いた俺が悪かった
enum { RED, BLUE, YELLOW } color;
void timeout()
{
if (color == RED) color = BLUE;
else if (color == BLUE) color = YELLOW;
else if (color == YELLOW) color = RED;
}
enum { RED, BLUE, YELLOW } color;
void coroutine()
{
while (true)
{
color = RED;
yield;
color = BLUE;
yield;
color = YELLOW;
yield;
}
}
void timeout() { yield; }
171:名前は開発中のものです。
08/05/26 16:04:14 lNPZHMUK
INIT状態で点滅、resetでINITに遷移
殴るはtimeoutと同じ意味だから必要ないよな
enum { RED, BLUE, YELLOW, INIT } color;
void timeout()
{
if (color == INIT) color = RED;
else if (color == RED) color = BLUE;
else if (color == BLUE) color = YELLOW;
else if (color == YELLOW) color = RED;
}
void reset() { color = INIT; }
enum { RED, BLUE, YELLOW, INIT } color;
void coroutine()
{
color = INIT;
yield;
while (true)
{
color = RED;
yield;
color = BLUE;
yield;
color = YELLOW;
yield;
}
}
void timeout() { yield; }
void reset() { コルーチンリスタート(); }
172:名前は開発中のものです。
08/05/26 20:50:15 pgU86LI0
あれ、こんなスレあったんだ。
何年かゲームプログラム(非プロ)やってるけど、
この周りはどうしても複雑になるよね。以下この辺の処理の個人的感想。
・(いわゆる)タスクシステム
関数ポインタでジャンプやらStateパターン、Strategyパターンなど。
はまってた頃は多用したのだが、今ではシーンの遷移にしか使わない・・・
敵やら弾とかの状態遷移はif文分岐で困らん。
いわゆるUpdateやRenderの中でif文分岐の方が読みやすいよ。。。
・コルーチン、ファイバ、マイクロスレッド
エフェクトやら敵の動きのような処理を外だししたときに
スクリプト内で使うのみ。
組み込まれていない言語(C++とか)では使わない。
・スレッド
メイン、BGM再生、データ読み込み以外は不要。
デバッグ用のログ出力ウィンドウとか作成したときは別スレッドにする。
1キャラクタ1スレッドとかやった人いるのだろうか?
スレッドでつくると、スレッド生成時にそのスレッドのための
スタック領域(デフォルトだと1スレッドにつき、512kBだか1MBだっけ?)が必要ですよね。
もちろんサイズ変更はできるけど、少なくしてスタックオーバーフローで落ちる
限界を見極めるとか面倒すぎる気がする。
173:名前は開発中のものです。
08/05/26 21:45:04 QJtuJBIN
>・コルーチン、ファイバ、マイクロスレッド
>エフェクトやら敵の動きのような処理を外だししたときに
>スクリプト内で使うのみ。
なるほど、そういう使い分けなのね
>組み込まれていない言語(C++とか)では使わない。
継続やコルーチン的なことがやりにくいから?
可能ならやる?
174:名前は開発中のものです。
08/05/27 00:01:22 cvXssXEI
>継続やコルーチン的なことがやりにくいから?
>可能ならやる?
可能ならやるというか
その言語の通常の仕組みで記述できる範囲なら使います。
ただC++で書く場合なら、このスレでいうタスク(敵とか弾とか)のようなのは
外部ファイルに出します。
あと組み込みでない言語を細工してコルーチンを実装するのと
元々実装してある言語では、できることの範囲に差があるように思えます。
例えばコルーチンはコルーチン自体を入れ子にできると
便利ですよね。説明しづらいですが
エフェクト作成関数
{
coroutine エフェクトメイン
{
coroutine エフェクト座標操作{...}
coroutine エフェクト描画元画像位置操作{...}
エフェクト座標操作コルーチン起動
エフェクト描画元画像位置操作コルーチン起動
}
エフェクトメインコルーチン起動
}
のような感じで、関数やコルーチンの内側に次々と子の関数やコルーチンを生成できるようなの。
C++には内部関数すらないのでこういったのは難しいです。
(関数内に構造体を宣言して内部関数みたいなのはつくれますが
外部のローカル変数にはアクセスできない)
175:名前は開発中のものです。
08/05/27 00:38:38 5lsjU+J+
コルーチン的なことはスクリプトでやると言う人がちらほらいるね。
何を使ってるんだろう。
Lua? Squirrel? それとも独自実装スクリプトなのかな
>>173
>継続やコルーチン的なことがやりにくいから?
>可能ならやる?
C言語上のコルーチンは環境に左右されやすすぎない?
たとえば、ゲームプログラマが多分いま一番関わることが多いだろうDSで
C言語上のコルーチンを実装したとしても、
DSでは通常スタック領域をDTCMという高速メモリに割り当てているにも関わらず、
コルーチン呼び出し中はスタック領域をメインメモリ上に持っていくことになってしまい、
ローカル変数アクセスや関数呼び出しはガクンと遅くなると考えられる。
※以上のDSの話は以下の記載を根拠にした
URLリンク(meraman.dip.jp)
176:名前は開発中のものです。
08/05/27 08:13:36 tDqFmLHm
>>175
俺は独自実装スクリプト。lua だと、ちょっとスクリプタが辛そうだったんで。
177:名前は開発中のものです。
08/05/28 20:41:16 2pIaJOU5
>>172
ちょっとまって
横文字書いて満足しちゃってそうだから突っ込むけど
そのどれも>>111にあるみたいな
オブジェクト同士が絡むときの処理の何かを解決するの?
意味ねぇっていってんじゃん
わざわざそんな複雑にしていったい何がやりたいのか意味不明
ちょっとオナニー入ってない?
っていうのはね
なんか聞きなれない言葉多いじゃない?
そういうの複数人で開発するときやこういう掲示板で情報を共有しようってときに
すごく邪魔なのよホント
178:名前は開発中のものです。
08/05/28 20:47:29 DREncIEi
>>177
turemasuka
179:名前は開発中のものです。
08/05/28 20:50:08 2pIaJOU5
>>178
アフォ?
そんな部分どう組んだって完成すんだよ
問題はオブジェクト同士がかかわったときの管理をいかにうまく管理するかだ
そこに技術使わないで一体どこに技術を使うというのか?
逆にそれ以外好きにしろよw
180:名前は開発中のものです。
08/05/28 20:54:51 DREncIEi
タスクシステムのスレでそんなこといわれてもな。
181:名前は開発中のものです。
08/05/28 21:18:38 DREncIEi
>問題はオブジェクト同士がかかわったときの管理をいかにうまく管理するかだ
>そこに技術使わないで一体どこに技術を使うというのか?
ここについて話したい素直にそう書けばいいことでは。
182:名前は開発中のものです。
08/05/28 22:37:27 UT4Zgemv
これがいわゆるツンデレってやつかい?
183:名前は開発中のものです。
08/05/28 23:55:23 shc+nb/z
>>177
いったいどれが聞きなれない言葉?
ゲームプログラム特有の言葉は
>タスクシステム、いわゆるUpdateやRender、エフェクト、1キャラクタ、シーンの遷移、敵やら弾
くらいで、他はプログラムかじってたら知っていそうな用語ばかりだと思う。
と思ったが、かじってる言語によるわな。
スレッドのスタック領域ってなんですか? ってなってもおかしくないし、問題があるわけでもない。
>問題はオブジェクト同士がかかわったときの管理をいかにうまく管理
ここは同意。整然とかけない。
184:名前は開発中のものです。
08/05/28 23:57:06 Uls7k781
>>177が言ってる横文字って、デザインパターンのことじゃね?
デザインパターンは、プログラマ同士の簡潔な意思疎通に
役立つというのが利点のひとつだと思うけど、
デザインパターン自体が分かってもらえない場合は逆に混乱をまねく。
ゲーム業界にはデザパタは明らかに普及してないから、
>>117のような多分古株のプログラマから反発があるのは仕方ないかと・・・。
まあ、俺は>>172の味方だけどなw
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5140日前に更新/128 KB
担当:undef