読者です 読者をやめる 読者になる 読者になる

S.F. Page

Programming,Music,etc...

Box2D + WinRTでゲームを作る (20) – タイマー遷移コードの改良

Boost シューティングゲーム PPL/ConcRT C++ Windows ゲーム Box2D + WinRTでゲームを作る

タイマー遷移コードの改良

ゲームオーバー表示を数秒表示してメニューに戻るコードは作成できたけれども、表示をキャンセルしてすぐメニューに戻るようにし、このタイマー遷移コード自体を使いまわしできるようにしてみた。

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によるタスクはほんと便利だな。