13:タスク処理を実装する(3)

 それでは、CGameObjectクラスを管理するためのリストをプログラムに組み込むことにしましょう。リストにCGameObject以外の情報もあると管理がさらに簡単になります。今回は以下の情報が格納されたデータをリストに追加していくことにします。
  • CGameObjectのポインタ
  • 実行順位(キャラクターの重ね順などに柔軟に対応できる)
  • オブジェクトの名前(文字列でオブジェクトを検索できる)
  • リストから削除された場合、CGameObject*を
    delete
    するかどうか
    new
    で作成したオブジェクトを自動で削除できる)

 リストにデータを追加するための関数を作成します。同じ名称の関数が2つ用意されていますが、引数のデータが異なっているのであれば、コンパイラが状況に合わせた関数を自動で参照してくれます。これを関数の多重定義(オーバーロード)といいます。また、外部のstatic関数からもアクセスできるように、これらの関数はstatic属性にしています。  41行目に見慣れない関数「strcpy_s」が登場しています。これは文字列複製関数「strcpy」を拡張したもので、コピーできる上限をあらかじめ設定しておくことで、メモリの破壊を未然に防ぐ機能が追加されています。現時点でこの関数はマイクロソフト社の開発環境しか対応していませんが、ISOでも策定段階にはいっているので、近い将来は様々なCコンパイラが対応することになるでしょう。
 続いて、オブジェクトをリストから削除するための関数を追加します。このコードでは、削除したいゲームオブジェクトのポインタがリスト内に存在した場合は、その箇所をリストから削除し、そうでない場合は、リスト内の探索を続けるようにしています。  しかしながら、ここで少しばかり問題が発生します。ゲームタスク処理中にリストからデータを除去することもあるかと思うのですが、この状態でループ処理中にリストからデータを抜き取ってしまうと、イテレータが場所を参照できなくなるおそれがあるからです。

 そこで、タスク処理に利用しているイテレータをクラス内で共有し、削除するイテレータと、タスク処理を行っているイテレータが一致するときは、参照を失わないよう、あらかじめRemoveObject内でタスク処理側のイテレータをひとつ後に進めておきます。  最後にタスクをまとめて処理するための関数を作成して、オブジェクト管理ルーチンは完成です。  今回の講座までに作成したCGameObjectのプログラムサンプルをアーカイブ形式で用意しています。ダウンロードはこちらから。なお、このアーカイブファイルには優先度を指定してのオブジェクト削除ルーチンも組み込まれているので参考にしてください。WinMain関数に埋め込む作業は次回にて。