Cocos2dx(2.1.5)でCCRenderTextureを使っているプログラムがあったのだが、Androidでホームボタンなどで別アプリに遷移して戻ってくるとテクスチャに書き込めなくなるという現象があった。

幸い作り直せる内容だったので、別アプリから戻ってきた時に作りなおしてやることにした。アプリの復帰時にCocos2dxシステムで呼び出される AppDelegate::applicationWillEnterForeground() 内で現在のシーンを管理するレイヤーを取得してシーンの復帰処理を呼び出す、というふうにしていたがこれは結構面倒くさかった。またそのためにシーンのベースクラスに復帰用の仮想関数を用意してやるのだが、TransitionSceneでアニメーションさせている間はシステムが用意したシーンになってしまうので、除外しないといけないという問題もあった。

そんな時にデバッグでソースを追っかけてたら CCNotificationCenter というクラスがあることを知った。addObserver() で任意の名前の通知に対するオブザーバーを追加し、postNotification() でイベントを通知することができる。必要がなくなったら removeObserver() で削除できる。

これを使えば復帰処理を簡単に書けるようになる、バンザイ。Cocos2dxには EVENT_COME_TO_FOREGROUND などという文字列が定義してあるので通知されているのかと思ったけどどうやらされていないようなので、自分で定義した通知を使うことにする。

Cocos2d-x 3の場合

今どき Cocos2dx2の話も何なので、3でも調べてみた。3では EventDispatcher というものに組み込まれているようだ。この addCustomEventListener()addEventListenerWithSceneGraphPriority() などで登録し、dispatchCustomEvent() で通知を送ることができる。Director がシステムの EventDispatcher を保持しているので、それを使って登録、通知すればよい:

  auto listener = EventListenerCustom::create("FooEvent", [](EventCustom*) {
    CCLOG("FooEvent notified");
  });
  auto dispatcher = Director::getInstance()->getEventDispatcher();
  dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
  ...
  dispatcher->dispatchCustomEvent("FooEvent");