タイマー遷移コードの改良
ゲームオーバー表示を数秒表示してメニューに戻るコードは作成できたけれども、表示をキャンセルしてすぐメニューに戻るようにし、このタイマー遷移コード自体を使いまわしできるようにしてみた。
template <typename EventClass,int Resolution>
task<void> create_timer_task(int ms,GameMain^ main,cancellation_token& token)
{
return create_task([=]()
{
int count = ms;
while(count > 0 && !token.is_canceled()){
if(count < Resolution)
{
wait(count);
break;
} else {
wait(Resolution);
count -= Resolution;
}
}
},token).then([=](){
main->GetStateMachine().process_event(EventClass(main));
},Concurrency::task_continuation_context::use_current());
}
struct GameOver : msmf::state<>{
template <class Event, class Fsm>
void on_entry(Event const& ev, Fsm& )
{
GameMain^ g = ev.getGameMain();
create_timer_task<ev::TimeOver,100>(1000 * 3,g,token_.get_token());
//timer_task_ = Concurrency::create_task(
// [=]() -> void {
// Concurrency::wait(1000 * 3);
// }
// ).then([=]{
// g->GetStateMachine().process_event(ev::TimeOver(g));
// },Concurrency::task_continuation_context::use_current()
// );
}
void cancel(){token_.cancel();}
private:
cancellation_token_source token_;
// Concurrency::task<void> timer_task_;
};
タスクのキャンセルってどうすんのかなと思ったけど、意外と簡単に実装できるのであった。あとタスク自体変数で保持するのをやめた。スコープが外れても実行が完了されるまで維持されるとドキュメントに書いてあったので。このPPLによるタスクはほんと便利だな。