次の方法で共有


プレーヤ コンテキスト値の使い方

プレーヤ コンテキスト値の使い方

多くのアプリケーションでは、個々のプレーヤに何らかのデータを関連付けたいことがある。一方、プレーヤに関連するメッセージを受信したときには、そのデータにすばやくアクセスするためにある種の手段が必要になる。プレーヤ コンテキスト値の目的は、プレーヤ データへの効率的なアクセス手段を提供することにある。

  プレーヤ コンテキスト値を使うのは、IDirectPlay8Peer インターフェイスおよび IDirectPlay8Server インターフェイスだけである。IDirectPlay8Client インターフェイスにプレーヤ コンテキスト値は必要ない。 これは、クライアントがこのインターフェイスをサーバーとの通信のみに使い、他のクライアントとの通信には使わないためである。

プレーヤ コンテキスト値の定義

プレーヤ コンテキスト値を使うには、使用中のシステムに、個々のプレーヤに対応するデータ ブロックを、通常は構造体の形で保持する必要がある。プレーヤ コンテキスト値は、通常、各種プレーヤのデータ ブロックを指すポインタ配列のインデックスである。プレーヤからメッセージを受け取ったときに、テーブル内のプレーヤ識別子 (ID) を検索するなど、時間のかかる処理をしないで済む。プレーヤ コンテキスト値に格納されたインデックスを使うと、必要なポインタをすばやく取得できる。

プレーヤ コンテキスト値は、ゲームにプレーヤが追加されたことを通知する DPN_MSGID_CREATE_PLAYER メッセージを処理するときに定義する。ホストも、DPN_MSGID_INDICATE_CONNECT メッセージを処理するときに、プレーヤ コンテキスト値を定義できる。それ以降の DPN_MSGID_CREATE_PLAYER メッセージには、そのプレーヤ コンテキスト値が設定される。ホストは、そのメッセージを処理するときに、プレーヤ コンテキスト値を変更できる。プレーヤ コンテキスト値を作成するには :

  • プレーヤのデータを保持するための構造体を割り当てる。
  • プレーヤ データ配列にその構造体ポインタを追加する。
  • メッセージの DPN_MSGID_CREATE_PLAYER 構造体の pvPlayerContext メンバに、そのポインタのインデックスを割り当てる。

Microsoft® DirectPlay® では、データを取得して構造体に代入する方法が指定されていない。その問題は、個々のゲームで独自の方法により処理すること。

  プレーヤ コンテキスト値を定義できる場所は、DPN_MSGID_CREATE_PLAYER または DPN_MSGID_INDICATE_CONNECT メッセージ ハンドラ内のみである。DPN_MSGID_CREATE_PLAYER メッセージ ハンドラが戻ると、プレーヤ コンテキスト値が設定される。そのプレーヤに関連する以降のメッセージのプレーヤ コンテキスト値は、DPN_MSGID_CREATE_PLAYER メッセージ ハンドラが設定した値と等しくなる。関連するデータ構造体の内容は修正できるが、プレーヤ コンテキスト値自体は変更できない。

プレーヤ コンテキスト データの管理

プレーヤ コンテキスト値はごく簡単に取り扱えるが、注意する点がいくつかある。

プレーヤ コンテキスト値は、メッセージが届くたびにアクセスできると思われる有効なメモリ アドレスを、簡単に取得する手段である。ただし、アプリケーション内の異なった部分から、データのアクセスを同時に行わないように注意する必要がある。DirectPlay は、特定のプレーヤに関連するメッセージを継続して処理する。 これにより、同じプレーヤからの 2 つのメッセージを同時に処理することはなくなる。データ構造体は、コールバック メッセージ ハンドラからアクセスする限り、安全にアクセスできる。ただし、多くのアプリケーションでは、メッセージ ハンドラ以外からプレーヤ データにアクセスする必要がある。

コールバック メッセージ ハンドラ以外からデータにアクセスするアプリケーションでは、構造体をロックするある種のグローバルなメカニズムを用意して、同時アクセスを避けなければならない。開発の初期にはそのようなロック メカニズムが必要ないとしても、必要になる場合を想定して初めから組み込んでおいた方がよい。プレーヤ コンテキスト値が配列のインデックスである場合は、その配列を安全に読み取り、更新することにも注意しなければならない。

プレーヤのデータ構造体の割り当てを誤って早く解除しないこと。プレーヤがゲームを抜けるときは、通常、プレーヤのデータ構造体の割り当てを解除し、関連するメモリを解放する必要がある。しかし、DPN_MSGID_DESTROY_PLAYER メッセージを受け取ってすぐに構造体の割り当てを解除することには、注意が必要である。コールバック メッセージ ハンドラ以外から構造体にアクセスするアプリケーションでは、メッセージが届いたときに、そのデータがまだ使われている可能性がある。メッセージを受け取ってすぐに構造体の割り当てを解除すると、アプリケーションの他の部分が失敗することがある。

誤って早く構造体の割り当てを解除することを避けるには、アプリケーションレベルのロック メカニズムを用意するだけでなく、ある種の参照カウントを実装するとよい。構造体を作成するとき、および構造体を使うたびに、参照カウントをインクリメントする。DPN_MSGID_DESTROY_PLAYER メッセージ ハンドラを含め、構造体の使用を終了するたびに、参照カウントをデクリメントする。参照カウントが 0 でない限り、構造体はアプリケーションのどこかからアクセスされている。参照カウントが 0 に戻るまで、構造体の割り当てを解除しないこと。