# 通知設計書 69-NOTIFICATION_EDITOR_POST_SAVE

## 概要

本ドキュメントは、Godotエンジンにおける`NOTIFICATION_EDITOR_POST_SAVE`通知の設計仕様を定義する。この通知はGodotエディタでシーンが保存された直後に、シーン内のすべてのノードに対して送信される内部通知である。

### 本通知の処理概要

`NOTIFICATION_EDITOR_POST_SAVE`通知は、エディタがシーンをディスクに保存した直後のタイミングで、対象シーンのすべてのノードに対して送信される。これにより、各ノードは保存前に行った一時的な状態変更を元に戻すことができる。

**業務上の目的・背景**：`NOTIFICATION_EDITOR_PRE_SAVE`で行った保存前の状態調整（エディタ専用データの除外、一時フラグの設定など）を元に戻し、エディタでの作業を継続できる状態に復帰させる必要がある。例えば、Skeleton3Dは保存後にsavingフラグをfalseに戻す。

**通知の送信タイミング**：EditorNode::_save_scene()メソッド内で、ResourceSaver::save()による保存処理が完了した後にpropagate_notificationで送信される。

**通知の受信者**：保存対象シーンのルートノードおよびその全子孫ノード。_notificationメソッドで受信して処理する。

**通知内容の概要**：通知値は`9002`（Node::NOTIFICATION_EDITOR_POST_SAVE）。追加のパラメータは含まれない。

**期待されるアクション**：受信者は保存後の状態復元（savingフラグのクリア、一時状態の復元、エディタモードへの復帰など）を実装する。

## 通知種別

アプリ内通知（エンジン内部通知・エディタ専用）

## 送信仕様

### 基本情報

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

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

シーンのルートノードに対してpropagate_notificationで送信され、全子孫ノードに伝播される。

## 通知テンプレート

### エンジン内部通知の場合

| 項目 | 内容 |
|-----|------|
| 通知定数名 | NOTIFICATION_EDITOR_POST_SAVE |
| 通知値 | 9002 |
| 定義クラス | Node |

### 通知ペイロード

通知に追加データは含まれない。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| p_notification | 通知ID（9002） | エンジン内部 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 保存完了 | ResourceSaver::save()成功 | 保存処理完了 | シーンがディスクに保存された後 |
| 保存失敗後も | エラー発生 | 保存試行後 | 保存が失敗した場合でも状態復元のため送信 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| PRE_SAVE未送信 | PRE_SAVEが送信されていない場合（異常ケース） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[NOTIFICATION_EDITOR_PRE_SAVE送信済み] --> B[PackedScene::pack]
    B --> C[ResourceSaver::save]
    C --> D{保存成功?}
    D -->|Yes| E[保存成功処理]
    D -->|No| F[エラー表示]
    E --> G[scene->propagate_notification POST_SAVE]
    F --> G
    G --> H[各ノードの_notification受信]
    H --> I[保存後復元処理]
    I --> J[処理終了]
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。

### 更新テーブル一覧

本通知はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 復元失敗 | POST_SAVE処理中のエラー | ログに記録し処理継続 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ユーザー操作依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

エディタ使用時のみ

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

- 本通知はエディタ内部の通知であり、ゲーム実行時には発生しない
- TOOLS_ENABLED（エディタビルド）でのみコンパイルされる

## 備考

- 対となる通知として`NOTIFICATION_EDITOR_PRE_SAVE`（9001）がある
- Skeleton3Dでは`saving = false`フラグをクリアし、通常のアニメーション処理を再開
- PRE_SAVEとPOST_SAVEは必ずペアで発生する

---

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

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

### 推奨読解順序

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

まず、通知定数の定義場所を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | node.h | `scene/main/node.h` | 502行目でNOTIFICATION_EDITOR_POST_SAVEが9002として定義されていることを確認 |

**読解のコツ**: PRE_SAVE(9001)とPOST_SAVE(9002)が連番で定義されている点に注目する。

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

通知を発火するEditorNode::_save_sceneメソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | editor_node.cpp | `editor/editor_node.cpp` | 2491行目で`scene->propagate_notification(NOTIFICATION_EDITOR_POST_SAVE);`が呼び出される |

**主要処理フロー**:
1. **2414行目**: NOTIFICATION_EDITOR_PRE_SAVE送信
2. **2438行目**: PackedScene::pack()
3. **2451行目**: ResourceSaver::save()
4. **2466-2489行目**: 保存成功/失敗に応じた処理
5. **2491行目**: `scene->propagate_notification(NOTIFICATION_EDITOR_POST_SAVE);`

#### Step 3: 受信側の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | 307-309行目でNOTIFICATION_EDITOR_POST_SAVEを処理してsaving=falseをクリア |

**主要処理フロー**:
- **307行目**: `case NOTIFICATION_EDITOR_POST_SAVE:`
- **308行目**: `saving = false;`

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

```
EditorNode::_save_scene()
    │
    ├─ scene->propagate_notification(NOTIFICATION_EDITOR_PRE_SAVE)
    │
    ├─ PackedScene::pack(scene)
    │
    ├─ ResourceSaver::save()
    │
    └─ scene->propagate_notification(NOTIFICATION_EDITOR_POST_SAVE)
           │
           └─ 各ノードの_notification()
                  ├─ Skeleton3D: saving = false
                  └─ その他ノード: 保存後処理
```

### データフロー図

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

シーン保存       ───▶ ResourceSaver::save()        ───▶ 保存完了
完了                          │                               │
                              ▼                               ▼
                    propagate_notification        各ノード保存後処理
                    (POST_SAVE)                            │
                              │                               ▼
                              ▼                   状態復元完了
                    各ノードの_notification          │
                                                              ▼
                                                    エディタ作業継続可能
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| node.h | `scene/main/node.h` | ソース | 通知定数定義 |
| node.cpp | `scene/main/node.cpp` | ソース | Node基底クラス実装 |
| editor_node.cpp | `editor/editor_node.cpp` | ソース | エディタノード・保存処理 |
| skeleton_3d.cpp | `scene/3d/skeleton_3d.cpp` | ソース | Skeleton3D実装（savingフラグクリア） |
| control.cpp | `scene/gui/control.cpp` | ソース | Control実装 |
| skeleton_2d.cpp | `scene/2d/skeleton_2d.cpp` | ソース | Skeleton2D実装 |
| spring_bone_simulator_3d.cpp | `scene/3d/spring_bone_simulator_3d.cpp` | ソース | SpringBoneSimulator実装 |
