# 通知設計書 3-disconnected

## 概要

本ドキュメントは、three.jsライブラリにおける`disconnected`イベント通知の設計について記載する。`disconnected`イベントは、WebXRコントローラーがXRセッションから切断された際に発火するイベントである。

### 本通知の処理概要

`disconnected`イベントは、WebXR APIを使用したVR/ARアプリケーションにおいて、コントローラーの切断を検知し、アプリケーションがコントローラーの状態変更に適切に対応できるようにするための重要なイベントである。

**業務上の目的・背景**：WebXRアプリケーションでは、ユーザーがVRコントローラーを物理的に置いた場合や、バッテリー切れ、通信範囲外への移動等でコントローラーが切断されることがある。`disconnected`イベントにより、アプリケーションはコントローラーの喪失を検知し、代替入力方法の提供、UIのフォールバック表示、進行中の操作のキャンセル等を行える。

**通知の送信タイミング**：WebXRセッション中に入力ソース（XRInputSource）が削除された際、`inputsourceschange`イベントを受けてWebXRControllerの`disconnect()`メソッドが呼び出され、`disconnected`イベントが発火される。また、XRセッション終了時にも全コントローラーに対してdisconnectが呼び出される。

**通知の受信者**：`disconnected`イベントの受信者は、XRコントローラーの各座標空間（targetRay、grip、hand）を表すGroupオブジェクトに登録されたリスナーである。

**通知内容の概要**：イベントオブジェクトには`type: 'disconnected'`と`data`プロパティが含まれ、`data`には切断されたXRInputSourceオブジェクトへの参照が設定される。

**期待されるアクション**：受信者は、切断されたコントローラーに関連する3Dモデルをシーンから削除し、入力ハンドラーを無効化する。また、ユーザーに対して切断の通知を表示することもある。

## 通知種別

アプリ内イベント通知（EventDispatcherパターン）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無 |

### 送信先決定ロジック

WebXRControllerクラスの`dispatchEvent()`メソッドにより、targetRay、grip、handの3つのGroupオブジェクトに対して順次イベントが送信される。

## 通知テンプレート

### イベントオブジェクト形式

| 項目 | 内容 |
|-----|------|
| type | 'disconnected' |
| data | XRInputSourceオブジェクト |
| target | dispatchEvent実行元Groupオブジェクト（自動設定） |

### イベントオブジェクト例

```javascript
{
  type: 'disconnected',
  data: XRInputSource,
  target: <Group>
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | イベントタイプ | 固定値 'disconnected' | Yes |
| data | XR入力ソース | WebXR API XRInputSource | Yes |
| target | イベント発火元オブジェクト | EventDispatcher.dispatchEvent内で自動設定 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| WebXR API | inputsourceschange | event.removedに入力ソースが存在 | XRセッションで入力ソースが削除された時 |
| WebXR API | sessionend | セッション終了時 | XRセッション終了時に全コントローラーに対して発火 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Groupが未初期化 | _targetRay、_grip、_handがnullの場合、そのGroupへの通知はスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[XRSession inputsourceschange発火] --> B[onInputSourcesChange処理]
    B --> C[event.removedをループ処理]
    C --> D[controller.disconnect inputSource 呼び出し]
    D --> E[dispatchEvent type: disconnected, data: inputSource]
    E --> F[_targetRay.visible = false]
    F --> G[_grip.visible = false]
    G --> H[_hand.visible = false]
    H --> I[終了]
```

## データベース参照・更新仕様

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リスナーエラー | リスナー関数内で例外が発生 | 例外はキャッチされず呼び出し元に伝播 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

制限なし

### 配信時間帯

制限なし（XRセッション中のみ発火）

## セキュリティ考慮事項

- connected同様、XRInputSourceオブジェクトへの参照を含む

## 備考

- disconnect後、各座標空間のvisibleプロパティがfalseに設定される
- セッション終了時には、登録された全コントローラーに対してdisconnectが呼び出される

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebXRController.js | `src/renderers/webxr/WebXRController.js` | 187-211行目のdisconnect()メソッド |

**主要処理フロー**:
1. **189行目**: `this.dispatchEvent( { type: 'disconnected', data: inputSource } )`でイベント発火
2. **191-207行目**: 各座標空間のvisibleをfalseに設定

#### Step 2: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WebXRManager.js | `src/renderers/webxr/WebXRManager.js` | 553-566行目（inputsourceschange）、224-234行目（sessionend） |

### プログラム呼び出し階層図

```
XRSession
    │
    ├─ inputsourceschange イベント
    │      │
    │      └─ onInputSourcesChange()
    │             │
    │             └─ controller.disconnect(inputSource)
    │
    └─ end イベント
           │
           └─ onSessionEnd()
                  │
                  └─ controllers[i].disconnect(inputSource)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WebXRController.js | `src/renderers/webxr/WebXRController.js` | ソース | disconnectedイベント発火 |
| WebXRManager.js | `src/renderers/webxr/WebXRManager.js` | ソース | disconnectメソッド呼び出し元 |
