# 通知設計書 18-NOTIFICATION_READY

## 概要

本ドキュメントは、Godotエンジンにおける `NOTIFICATION_READY` 通知の設計と実装について記述する。この通知はNodeクラスの基本的なライフサイクル通知の一つで、ノードとそのすべての子ノードがシーンツリーに入った後に発火する、最も重要な初期化完了タイミングを提供する。

### 本通知の処理概要

`NOTIFICATION_READY` は、ノードが「準備完了」状態になった時に送信される通知である。これは、ノード自身とそのすべての子孫ノードがシーンツリーに入り、NOTIFICATION_ENTER_TREEを受け取った後に発火する。つまり、この通知を受け取った時点で、シーン全体が初期化済みであることが保証される。

**業務上の目的・背景**：ゲームやアプリケーション開発において、すべての初期化が完了した後に処理を開始したい場面は非常に多い。NOTIFICATION_READYは、ノードの初回準備完了時のみ発火する一度限りの通知であり、ゲームロジックの初期化、初期状態の設定、他のノードへの参照取得などを安全に行うことができる。

**通知の送信タイミング**：NOTIFICATION_READYは、以下の状況で送信される。(1) ノードがシーンツリーに初めて追加され、すべての子ノードのENTER_TREEが完了した後、(2) request_ready()が呼ばれた後に次回シーンツリーに入った時。通常、ノードの生涯で一度だけ発火する。

**通知の受信者**：シーンツリーに追加されるすべてのNodeおよびその派生クラスが受信者となる。子ノードが先に通知を受け取り、その後親ノードが通知を受け取る（深さ優先、ボトムアップ）。

**通知内容の概要**：通知値は整数定数13（Node::NOTIFICATION_READY）として定義されている。追加のパラメータは含まれない。

**期待されるアクション**：受信者は、ゲームロジックの初期化処理を実行する。_process、_physics_processの有効化、初期状態の設定、シグナル接続、他ノードへの参照取得などが典型的な処理である。

## 通知種別

Nodeライフサイクル通知（内部通知）

## 送信仕様

### 基本情報

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

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

シーンツリーに追加されるノードとそのすべての子孫ノードに対して、深さ優先ボトムアップで送信される。子ノードが先に通知を受け取り、その後親ノードが通知を受け取る。

## 通知テンプレート

### 定数定義

```cpp
enum {
    NOTIFICATION_ENTER_TREE = 10,
    NOTIFICATION_EXIT_TREE = 11,
    NOTIFICATION_MOVED_IN_PARENT = 12,
    NOTIFICATION_READY = 13,
    // ...
};
```

### GDScript使用例

```gdscript
extends Node

func _ready():
    # 準備完了時の処理
    print("ノードが準備完了しました: ", name)

    # 処理の有効化
    set_process(true)
    set_physics_process(true)

    # 他のノードへの参照取得（安全）
    var player = get_node("/root/Game/Player")

    # シグナル接続
    player.died.connect(_on_player_died)

# または_notification()を使用
func _notification(what):
    if what == NOTIFICATION_READY:
        _custom_ready()

func _custom_ready():
    # カスタム初期化処理
    pass

func _on_player_died():
    print("プレイヤーが死亡しました")
```

### 典型的な使用パターン

```gdscript
extends CharacterBody2D

@onready var sprite := $Sprite2D
@onready var collision := $CollisionShape2D
@onready var animation_player := $AnimationPlayer

func _ready():
    # @onreadyで取得したノードはここで使用可能
    sprite.modulate = Color.WHITE
    animation_player.play("idle")

    # 初期状態の設定
    velocity = Vector2.ZERO

    # 物理処理を有効化
    set_physics_process(true)

func _physics_process(delta):
    # 物理更新処理
    move_and_slide()
```

### request_ready()の使用例

```gdscript
extends Node

func _ready():
    print("_ready() called")

func reset_node():
    # 次回シーンツリーに入った時に再度_ready()を呼び出す
    request_ready()

func _on_need_reset():
    # ノードを一時的に削除して再追加
    var parent = get_parent()
    parent.remove_child(self)
    reset_node()
    parent.add_child(self)  # ここで再度_ready()が呼ばれる
```

## テンプレート変数

NOTIFICATION_READYはパラメータを持たないため、テンプレート変数は存在しない。

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ライフサイクル | シーンツリー追加完了 | ready_first == true | 初回のシーンツリー追加後 |
| プログラム | request_ready()呼び出し後 | ready_first がtrueにリセット | 明示的なready要求 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ready_first == false | 既にreadyが発火済みで、request_ready()が呼ばれていない |
| ready_notified == false | ENTER_TREEが完了していない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[_propagate_ready開始] --> B[ready_notified = true]
    B --> C[子ノードに再帰]
    C --> D[notification POST_ENTER_TREE]
    D --> E{ready_first?}
    E -->|Yes| F[ready_first = false]
    F --> G[notification READY]
    G --> H[emit_signal ready]
    H --> I[完了]
    E -->|No| I
```

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

### 参照テーブル一覧

該当なし（NOTIFICATION_READYはデータベースを使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 特になし | - | - |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- NOTIFICATION_READYはエンジン内部で管理され、ユーザーコードから直接トリガーすることは推奨されない
- _ready()内で長時間の処理を行うとフレームレートに影響するため、重い処理はcall_deferred()で遅延させることを推奨

## 備考

- _ready()は通常、ノードの生涯で一度だけ呼ばれる
- request_ready()を呼ぶことで、次回シーンツリーに入った時に再度_ready()を発火させることができる
- _ready()の前にNOTIFICATION_POST_ENTER_TREEが発火する
- _ready()発火後にreadyシグナルが発火する
- GDScriptのGDVIRTUAL_IS_OVERRIDDEN()で_process等がオーバーライドされているかチェックされ、自動的にset_process()などが呼ばれる

---

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

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

### 推奨読解順序

#### Step 1: 定数定義を理解する

通知値の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node.h | `scene/main/node.h` | NOTIFICATION_READY定数の定義 |

**主要処理フロー**:
- **454行目**: `NOTIFICATION_READY = 13`

#### Step 2: 伝播処理を理解する

通知がどのように子ノードに伝播するかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | node.cpp | `scene/main/node.cpp` | _propagate_ready()関数の実装 |

**主要処理フロー**:
1. **317-333行目**: _propagate_ready関数全体
2. **318行目**: `data.ready_notified = true`
3. **319-323行目**: 子ノードへの再帰
4. **326行目**: `notification(NOTIFICATION_POST_ENTER_TREE)`
5. **328-331行目**: ready_firstチェックとREADY通知

#### Step 3: 通知ハンドラを理解する

_notification()でのREADY処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | node.cpp | `scene/main/node.cpp` | _notification()内のNOTIFICATION_READY処理 |

**主要処理フロー**:
1. **249-274行目**: case NOTIFICATION_READY全体
2. **250-252行目**: _inputオーバーライドチェック
3. **254-256行目**: _shortcut_inputオーバーライドチェック
4. **258-260行目**: _unhandled_inputオーバーライドチェック
5. **262-264行目**: _unhandled_key_inputオーバーライドチェック
6. **266-268行目**: _processオーバーライドチェック
7. **269-271行目**: _physics_processオーバーライドチェック
8. **273行目**: `GDVIRTUAL_CALL(_ready)`

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

```
シーンツリーへの追加完了後
    │
    └─ Node::_propagate_ready()
           │
           ├─ data.ready_notified = true
           │
           ├─ 子ノードに再帰
           │      └─ child._propagate_ready()
           │
           ├─ notification(NOTIFICATION_POST_ENTER_TREE)
           │
           └─ if (data.ready_first)
                  │
                  ├─ data.ready_first = false
                  │
                  ├─ notification(NOTIFICATION_READY)
                  │      └─ Node::_notification()
                  │             ├─ _inputオーバーライドチェック → set_process_input()
                  │             ├─ _shortcut_inputオーバーライドチェック → set_process_shortcut_input()
                  │             ├─ _unhandled_inputオーバーライドチェック → set_process_unhandled_input()
                  │             ├─ _unhandled_key_inputオーバーライドチェック → set_process_unhandled_key_input()
                  │             ├─ _processオーバーライドチェック → set_process()
                  │             ├─ _physics_processオーバーライドチェック → set_physics_process()
                  │             └─ GDVIRTUAL_CALL(_ready)
                  │                    └─ GDScript: _ready()
                  │
                  └─ emit_signal(ready)
```

### データフロー図

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

ENTER_TREE完了          ───▶ _propagate_ready()    ───▶ ready_notified = true
                                    │
                                    ├─▶ 子ノードに再帰（ボトムアップ）
                                    │
                                    ├─▶ POST_ENTER_TREE通知
                                    │
                                    ├─▶ ready_firstチェック
                                    │       │
                                    │       └─▶ READY通知（初回のみ）
                                    │               │
                                    │               ├─▶ オーバーライドチェック
                                    │               │       ├─▶ set_process_input()
                                    │               │       ├─▶ set_process()
                                    │               │       └─▶ set_physics_process()
                                    │               │
                                    │               └─▶ GDVIRTUAL_CALL(_ready)
                                    │
                                    └─▶ readyシグナル発火
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node.h | `scene/main/node.h` | ヘッダ | Node クラス定義、NOTIFICATION_READY定数 |
| node.cpp | `scene/main/node.cpp` | ソース | _propagate_ready()、_notification()実装 |
| scene_tree.h | `scene/main/scene_tree.h` | ヘッダ | SceneTreeクラス定義 |
| scene_tree.cpp | `scene/main/scene_tree.cpp` | ソース | シーンツリー管理 |
| Node.xml | `doc/classes/Node.xml` | ドキュメント | APIリファレンス |
