# 通知設計書 71-NOTIFICATION_ACCESSIBILITY_UPDATE

## 概要

本ドキュメントは、Godot Engineにおける`NOTIFICATION_ACCESSIBILITY_UPDATE`通知の設計仕様を記載する。この通知はアクセシビリティ情報の更新が必要な際にノードに送信され、スクリーンリーダーやその他の支援技術との連携を実現するための基盤となる。

### 本通知の処理概要

この通知は、アクセシビリティ情報（支援技術向けの情報）の更新が必要な場合にノードへ送信される。受信したノードは、DisplayServerを通じてアクセシビリティ要素の名前や子ノードの階層構造を更新する。

**業務上の目的・背景**：視覚障害者やその他の障害を持つユーザーがGodotで作成されたアプリケーションを利用できるようにするため、アクセシビリティ情報の動的な更新が必要となる。この通知により、ノードの状態変更（名前変更、子ノードの追加・削除、可視性の変更など）をリアルタイムで支援技術に伝達できる。

**通知の送信タイミング**：以下のイベントで通知がキューに追加される：
- ノードがシーンツリーに入った時（NOTIFICATION_ENTER_TREE発火後）
- `queue_accessibility_update()`メソッドが明示的に呼び出された時
- SceneTreeがアクセシビリティ更新を強制した時

**通知の受信者**：シーンツリー内のすべてのNodeおよびその派生クラス（Control、Node2D、Node3Dなど）が受信対象となる。ただし、エディタシーンの一部として編集中のノードは除外される。

**通知内容の概要**：通知自体にはデータは含まれないが、受信時に以下の情報が更新される：
- アクセシビリティ要素の名前（ノード名から取得）
- 子ノードのアクセシビリティ要素への参照

**期待されるアクション**：受信したノードは`_notification()`メソッド内で以下を実行する：
1. `get_accessibility_element()`でアクセシビリティ要素のRIDを取得
2. DisplayServerを通じてアクセシビリティ情報を更新
3. 必要に応じてカスタムのアクセシビリティ情報を追加

## 通知種別

アプリ内通知（エンジン内部通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 通知定数 | `NOTIFICATION_ACCESSIBILITY_UPDATE` |
| 通知値 | 3000 |
| 送信方式 | 同期（SceneTreeからの直接呼び出し） |
| 優先度 | 中 |
| リトライ | なし |

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

通知は以下の条件を満たすノードに送信される：
- シーンツリー内に存在する（`is_inside_tree() == true`）
- エディタシーンの一部ではない（`is_part_of_edited_scene() == false`）
- アクセシビリティサポートが有効なSceneTree内

## 通知テンプレート

### 通知パラメータ

| 項目 | 内容 |
|-----|------|
| 通知ID | 3000 |
| パラメータ | なし |
| 伝播方向 | 親から子へ |

### 処理テンプレート（GDScript）

```gdscript
func _notification(what):
    if what == NOTIFICATION_ACCESSIBILITY_UPDATE:
        var ae = get_accessibility_element()
        if ae.is_valid():
            # カスタムアクセシビリティ情報の設定
            DisplayServer.accessibility_update_set_role(ae, DisplayServer.ACCESSIBILITY_ROLE_BUTTON)
```

### 処理テンプレート（C++）

```cpp
void MyNode::_notification(int p_notification) {
    switch (p_notification) {
        case NOTIFICATION_ACCESSIBILITY_UPDATE: {
            RID ae = get_accessibility_element();
            ERR_FAIL_COND(ae.is_null());
            DisplayServer::get_singleton()->accessibility_update_set_name(ae, get_name());
            // カスタム処理
        } break;
    }
}
```

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| accessibility_element | アクセシビリティ要素のRID | `get_accessibility_element()` | Yes |
| node_name | ノードの名前 | `get_name()` | Yes |
| child_count | 子ノードの数 | `get_child_count()` | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ライフサイクル | NOTIFICATION_ENTER_TREE | アクセシビリティサポート有効 | ノードがツリーに入った時 |
| API呼び出し | queue_accessibility_update() | ツリー内かつ非エディタ | 明示的な更新要求 |
| システム | SceneTree::_accessibility_force_update() | アクセシビリティサポート有効 | 強制更新 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| is_part_of_edited_scene() == true | エディタで編集中のシーンには送信されない |
| !is_inside_tree() | ツリー外のノードには送信されない |
| アクセシビリティサポート無効 | SceneTreeでアクセシビリティが無効な場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[queue_accessibility_update呼び出し] --> B{is_inside_tree?}
    B -->|No| C[処理終了]
    B -->|Yes| D{is_part_of_edited_scene?}
    D -->|Yes| C
    D -->|No| E[SceneTree._accessibility_notify_change]
    E --> F[通知キューに追加]
    F --> G[次フレームで処理]
    G --> H[notification ACCESSIBILITY_UPDATE送信]
    H --> I[ノードの_notification呼び出し]
    I --> J[DisplayServer更新]
    J --> K[終了]
```

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

該当なし（本通知はエンジン内部の通知システムで処理され、データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| RID無効 | get_accessibility_element()がnullを返す | ERR_FAIL_CONDで処理中断 |
| DisplayServer未初期化 | シングルトン未取得 | 処理をスキップ |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1フレームあたり上限 | 制限なし（キューイングにより最適化） |
| 重複排除 | 同一ノードへの複数要求はマージ |

### 配信時間帯

制限なし（ゲーム実行中いつでも送信可能）

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

- アクセシビリティ情報にはノード名が含まれるため、センシティブな情報をノード名に含めない
- DisplayServerとの通信はエンジン内部で行われるため、外部からの改ざんリスクは低い

## 備考

- この通知はGodot 4.xで追加されたアクセシビリティシステムの一部
- AccessKitドライバーを使用してクロスプラットフォームでアクセシビリティをサポート
- Controlノードは追加のアクセシビリティ情報（ロール、状態など）を提供できる

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

通知システムとアクセシビリティ要素の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node.h | `scene/main/node.h` | NOTIFICATION_ACCESSIBILITY_UPDATE定数（値3000）とaccessibility_element RIDメンバ |
| 1-2 | display_server.h | `servers/display_server.h` | アクセシビリティ関連APIの定義 |

**読解のコツ**: `data.accessibility_element`はミュータブルなRIDで、遅延初期化される。通知処理時に初めて作成されることもある。

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

通知の発火元を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node.cpp | `scene/main/node.cpp` | queue_accessibility_update()メソッド（行3736-3740） |

**主要処理フロー**:
1. **行3736-3737**: `is_inside_tree()` && `!is_part_of_edited_scene()`チェック
2. **行3738**: `data.tree->_accessibility_notify_change(this)`呼び出し

#### Step 3: 通知処理を理解する

通知受信時の処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | node.cpp | `scene/main/node.cpp` | _notification()メソッド内のNOTIFICATION_ACCESSIBILITY_UPDATEケース（行69-89） |

**主要処理フロー**:
- **行69**: `case NOTIFICATION_ACCESSIBILITY_UPDATE:`開始
- **行70**: `get_accessibility_element()`でRID取得
- **行71**: RIDの有効性チェック
- **行73**: `accessibility_update_set_name()`で名前を設定
- **行76-88**: 子ノードのアクセシビリティ要素を追加

#### Step 4: SceneTreeの処理を理解する

SceneTreeでの通知管理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | scene_tree.cpp | `scene/main/scene_tree.cpp` | _accessibility_notify_change()メソッド |

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

```
Node::queue_accessibility_update()
    │
    └─ SceneTree::_accessibility_notify_change(Node*)
           │
           └─ （内部キューに追加）
                  │
                  └─ Node::notification(NOTIFICATION_ACCESSIBILITY_UPDATE)
                         │
                         ├─ Node::get_accessibility_element()
                         │      └─ DisplayServer::accessibility_create_element()
                         │
                         └─ DisplayServer::accessibility_update_set_name()
                         └─ DisplayServer::accessibility_update_add_child()
```

### データフロー図

```
[入力]               [処理]                    [出力]

ノード状態変更 ───▶ queue_accessibility   ───▶ アクセシビリティ
 - 名前変更          _update()                  要素の更新
 - 子追加/削除           │                          │
 - 可視性変更            ▼                          ▼
                    SceneTree              DisplayServer
                    キュー管理                 API呼び出し
                         │                          │
                         ▼                          ▼
                    notification           支援技術への
                    (3000)                 情報伝達
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node.h | `scene/main/node.h` | ヘッダ | 通知定数とアクセシビリティAPI宣言 |
| node.cpp | `scene/main/node.cpp` | ソース | 通知処理とqueue_accessibility_update実装 |
| scene_tree.h | `scene/main/scene_tree.h` | ヘッダ | アクセシビリティ通知管理宣言 |
| scene_tree.cpp | `scene/main/scene_tree.cpp` | ソース | アクセシビリティ通知キュー管理 |
| display_server.h | `servers/display_server.h` | ヘッダ | アクセシビリティAPI宣言 |
| accessibility_driver_accesskit.cpp | `drivers/accesskit/accessibility_driver_accesskit.cpp` | ソース | AccessKitドライバー実装 |
| Node.xml | `doc/classes/Node.xml` | ドキュメント | 公式ドキュメント定義 |
