> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 非同期 Lobby and Matchmaking C++ SDK 操作ガイド

> PlayFab Lobby and Matchmaking C++ SDK での非同期操作、ポーリング、状態変更通知を理解し、マルチプレイヤー タイトル向けのベスト プラクティスを学びます。

# 非同期操作と通知

低速または計算コストの高い操作に対して、PlayFab Lobby and Matchmaking SDK は非同期 API を公開します。非同期 API により、コストの高い操作や低速な操作をメイン スレッドから開始し、任意のスレッドでそれらの操作の完了をポーリングできます。同じポーリング メカニズムは、SDK の更新に関する非同期通知をタイトル コードに配信するためにも使用されます。このページでは、PlayFab Lobby and Matchmaking SDK の非同期 API パターンと、それらに対してプログラミングする際のベスト プラクティスの概要を説明します。

## 基本的な API パターン

PlayFab Lobby and Matchmaking SDK には、把握しておくべき非同期 API パターンが 2 種類あります:

1. [非同期操作](#asynchronous-operations)
2. [非同期通知](#asynchronous-notifications)

### 非同期操作

SDK の非同期 API は簡単に使用できます。非同期操作を開始して完了する一般的なパターンは次のとおりです:

1. 選択した非同期 API に対して通常のメソッド呼び出しを行います。よく使用される非同期操作には次のようなものがあります:
   * [PFMultiplayerCreateAndJoinLobby](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pfmultiplayercreateandjoinlobby)。
   * [PFMultiplayerJoinLobby](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pfmultiplayerjoinlobby)。
   * [PFLobbyPostUpdate](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pflobbypostupdate)。
   * [PFMultiplayerCreateMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayercreatematchmakingticket)。

2. API の **HRESULT** 戻り値を **SUCCEEDED()** または **FAILED()** マクロで確認します。この同期的に返される値は、操作が正常に開始されたかどうかを示します。

<Warning>
  非同期 API 呼び出しからの同期戻り値は、操作が正常に **完了** したかどうかは示 **しません**。同期エラーと非同期エラーの詳細については、SDK の [エラー処理ドキュメント](/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-errors#synchronous-vs-asynchronous-errors) を参照してください。
</Warning>

3. [PFMultiplayerStartProcessingLobbyStateChanges()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pfmultiplayerstartprocessinglobbystatechanges) または [PFMultiplayerStartProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) によって提供される、関連する操作の「completion state change (完了状態変更)」を探すことで、非同期操作の完了をポーリングします。**PFMultiplayerCreateAndJoinLobby()** の関連する「completion state change」の例は [PFLobbyCreateAndJoinLobbyCompletedStateChange](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/structs/pflobbycreateandjoinlobbycompletedstatechange) です。「state changes」とは何か、およびそれらがどのように機能するかの詳細については、[状態変更](#state-changes) セクションを参照してください。

4. completion state change の **result** 値を確認して、操作が成功したか失敗したかを判断します。これらのエラー値の詳細については、SDK の [エラー処理ドキュメント](/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-errors#synchronous-vs-asynchronous-errors) を参照してください。

### 非同期通知

一部の機能は、Lobby and Matchmaking SDK への変更を非同期通知として生成します。

一般的な通知には次のものがあります:

1. [ロビー更新通知](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/structs/pflobbyupdatedstatechange)。
2. [ロビー切断通知](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/structs/pflobbydisconnectingstatechange)。
3. [マッチメイキング チケット ステータス変更通知](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingticketstatuschangedstatechange)。

これらの非同期通知は、[PFMultiplayerStartProcessingLobbyStateChanges()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pfmultiplayerstartprocessinglobbystatechanges) および [PFMultiplayerStartProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) を通じて「state changes」として SDK から提供されます。

「state changes」とは何か、およびそれらがどのように機能するかの詳細については、[状態変更](#state-changes) セクションを参照してください。

## 状態変更

Lobby and Matchmaking SDK の非同期 API モデルは、[PFLobbyStateChange](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/structs/pflobbystatechange) および [PFMatchmakingStateChange](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingstatechange) 構造体を中心に構築されています。**PFLobbyStateChanges** はロビー サブシステムの変更を通知し、**PFMatchmakingStateChanges** はマッチメイキング サブシステムの変更を通知します。

これらの「state changes」は、SDK からのイベントの非同期通知です。これらの通知は内部でキューに入れられ、[PFMultiplayerStartProcessingLobbyStateChanges()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/functions/pfmultiplayerstartprocessinglobbystatechanges) および [PFMultiplayerStartProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) を呼び出すことで処理します。これらの関数は、(それぞれの API サブシステムの) すべてのキューに入れられた state changes をリストとして返します。反復処理して個別に処理できます。各 state change には、通知されている特定の state change を判別するために検査できる対応する *stateChangeType* フィールドがあります。どの state change が提供されているかがわかったら、一般的な **PFLobbyStateChange** または **PFMatchmakingStateChange** 構造体を、より具体的な state change 構造体の型にキャストして、そのイベントの特定のデータを検査できます。

通常、state change の処理は、各 state change をハンドラーに委任する単純な switch ステートメントとして実装されます。

**PFMultiplayerStartProcessingLobbyStateChanges** または **PFMultiplayerStartProcessingMatchmakingStateChanges** からの state changes のリストが処理されたら、それぞれ [PFMultiplayerFinishProcessingMatchmakingStateChanges()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerfinishprocessingmatchmakingstatechanges) または [PFMultiplayerFinishProcessingMatchmakingStateChanges()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerfinishprocessingmatchmakingstatechanges) に返す必要があります。

```cpp theme={null}
//
// Process Lobby state changes
//
uint32_t lobbyStateChangeCount;
const PFLobbyStateChange * const * lobbyStateChanges;
HRESULT hr = PFMultiplayerStartProcessingLobbyStateChanges(m_pfmHandle, &lobbyStateChangeCount, &lobbyStateChanges);
if (FAILED(hr))
{
    return hr;
}

for (uint32_t i = 0; i < lobbyStateChangeCount; ++i)
{
    const PFLobbyStateChange* stateChange = lobbyStateChanges[i];
    switch (stateChange->stateChangeType)
    {
        case PFLobbyStateChangeType::CreateAndJoinLobbyCompleted:
        {
            HandleCreateAndJoinLobbyCompleted(
                static_cast<const PFLobbyCreateAndJoinLobbyCompletedStateChange*>(stateChange));
            break;
        }
        // add other state change handlers here
    }
}

hr = PFMultiplayerFinishProcessingLobbyStateChanges(m_pfmHandle, lobbyStateChangeCount, lobbyStateChanges);
if (FAILED(hr))
{
    return hr;
}

//
// Process Match state changes
//
uint32_t matchStateChangeCount;
const PFMatchmakingStateChange * const * matchStateChanges;
hr = PFMultiplayerStartProcessingMatchmakingStateChanges(m_pfmHandle, &matchStateChangeCount, &matchStateChanges);
if (FAILED(hr))
{
    return hr;
}

for (uint32_t i = 0; i < matchStateChangeCount; ++i)
{
    const PFMatchmakingStateChange* stateChange = matchStateChanges[i];
    switch (stateChange->stateChangeType)
    {
        case PFMatchmakingStateChangeType::TicketStatusChanged:
        {
            HandleMatchmakingTicketStatusChanged(
                static_cast<const PFMatchmakingTicketStatusChangedStateChange*>(stateChange));
            break;
        }
        // add other state change handlers here
    }
}

hr = PFMultiplayerFinishProcessingMatchmakingStateChanges(m_pfmHandle, matchStateChangeCount, matchStateChanges);
if (FAILED(hr))
{
    return hr;
}
```

## 非同期操作コンテキスト

各非同期 API には `void* asyncContext` パラメーターが含まれます。この値はパススルー パラメーターで、**PFMultiplayerStartProcessingLobbyStateChanges()** または **PFMultiplayerStartProcessingMatchmakingStateChanges()** によって提供されると、この API 呼び出しの関連する completion state change に設定されます。

この値は、非同期 API 呼び出しに任意のポインター サイズのコンテキストを付加するメカニズムを提供します。これらのコンテキストは、次のような多くのシナリオで使用できます:

1. タイトル固有のデータを SDK 呼び出しに関連付ける
2. 共有識別子で複数の非同期操作を結び付ける

これらの非同期コンテキストは SDK の使用に必須ではありませんが、一部のタイトル ロジックを書きやすくするのに役立つ場合があります。

## 操作のキューイング

非同期 API を扱う際、より大規模な非同期フローの一部として複数の非同期操作を順次実行する必要があることがよくあります。

Lobby and Matchmaking SDK での 1 つの例は、ロビーを作成し、そのロビーへの招待をフレンドに送信することです。直列化すると、このフローは次のようになります:

1. **PFMultiplayerCreateAndJoinLobby()** を呼び出して PlayFab ロビーを作成して参加します。
2. **PFLobbyCreateAndJoinLobbyCompletedStateChange** がロビーの作成と参加が正常に行われたことを反映するまで待ちます。
3. 招待するフレンドごとに **PFLobbySendInvite()** を呼び出します。
4. **PFLobbySendInviteCompletedStateChange** が招待が正常に送信されたことを反映するまで待ちます。

より複雑なフローやタイトル ロジックの場合、この直列化されたパターンが適切かもしれません。ただし、より単純なフローの場合、SDK はタイトル コードを簡略化することを意図した代替手段を提供します:

SDK の多くの非同期 API は、前の操作が完全に完了する前の依存操作のキューイングをサポートしています。前の例から、ロビーが正常に作成されたことを確認する前でも、そのロビーへの招待を送信できます。

事実上、キューイングにより、非同期操作のコレクションをまとめてバンドルし、一度にすべてを開始し、エラー処理を単一の失敗地点に集約できます。

```cpp theme={null}
PFLobbyHandle newLobby;
HRESULT hr = PFMultiplayerCreateAndJoinLobby(m_pfmHandle, myPlayerEntityId, newLobbyConfiguration, nullptr, nullptr, &newLobby);
if (SUCCEEDED(hr))
{
    for (size_t i = 0; SUCCEEDED(hr) && i < friends.size(); ++i)
    {
        hr = PFLobbySendInvite(m_pfmHandle, myPlayerEntityId, friends[i], nullptr);
    }

    if (SUCCEEDED(hr))
    {
        m_lobby = newLobby;
        Log("Created lobby and invited %zu friends!", friends.size());
    }
    else
    {
        // For the purposes of demonstration, we could have a policy that we shouldn't bother with any lobbies where
        // we couldn't invite all of our friends.
        (void) PFLobbyLeave(newLobby, myPlayerEntityId, nullptr);
    }
}
```

## 非同期作業の制御

ライブラリとタイトルのコア CPU ワークロード間の CPU 競合を避けるため、タイトルが非同期作業を実行する場所を制御する必要がある場合があります。

Lobby and Matchmaking SDK では、[スレッド アフィニティの制御](#controlling-thread-affinity) によって非同期作業の実行方法を制御できます。

### スレッド アフィニティの制御

既定では、非同期の SDK 作業は慎重に制御されたバックグラウンド スレッドで実行されます。一部のタイトルでは、CPU 競合を避けるために、これらのバックグラウンド スレッドが *どこで* スケジュールされるかを大まかに制御する必要があります。

これらのタイトルのために、Lobby and Matchmaking SDK は [PFMultiplayerSetThreadAffinityMask()](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/functions/pfmultiplayersetthreadaffinitymask) を提供しています。サポートされているプラットフォームでは、SDK のバックグラウンド スレッドで使用される CPU コアを制限できます。これにより、特定のコアを競合なしに独自の CPU ワークロード用に確保することが保証できます。


## Related topics

- [Lobby and Matchmaking C++ SDK エラーの処理](/ja-jp/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-errors.md)
- [Unity 用 PlayFab Multiplayer スタート ガイド](/ja-jp/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-sdk-getting-started.md)
- [Multiplayer Android スタート ガイド](/ja-jp/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/android-specific-requirements.md)
- [Lobby SDK クイックスタート](/ja-jp/services/playfab/multiplayer/lobby/lobby-getting-started.md)
- [PlayFab 統合 SDK でのメモリ管理](/ja-jp/services/playfab/sdks/unified-sdk/memory-management.md)
