# 機能設計書 25-End

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるEnd機能の設計仕様を記述する。この機能は、Begin関数で開始したウィンドウをウィンドウスタックからポップし、ウィンドウの終了処理を行う関数である。

### 本機能の処理概要

**業務上の目的・背景**：Begin関数とペアで使用され、ウィンドウのライフサイクルを完結させる。即時モードGUIにおいて、ウィンドウの開始と終了を明示的に制御することで、ネストされたウィンドウやコンテキストの適切な管理を実現する。End関数はウィンドウのクリーンアップ処理、スタックの復元、およびエラーリカバリを担当する。

**機能の利用シーン**：
- Begin関数で開始したウィンドウを終了する場合
- ウィンドウ内のウィジェット追加が完了した後
- Begin関数の戻り値に関わらず、必ず呼び出す必要がある

**主要な処理内容**：
1. 現在のウィンドウのカラムが開いている場合は終了する
2. クリップ矩形をポップする
3. フォーカススコープをポップする
4. ロギングが有効な場合は終了処理を行う
5. ウィンドウスタックからポップする
6. 前のウィンドウを現在のウィンドウとして復元する

**関連システム・外部連携**：ImGuiのウィンドウ管理システム、描画システム、ロギングシステムと連携する。

**権限による制御**：特になし。すべてのユーザーが任意のタイミングで呼び出し可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Demo Window | 主機能 | ウィンドウの終了処理 |
| 2 | Metrics/Debugger Window | 主機能 | ウィンドウの終了処理 |
| 3 | Debug Log Window | 主機能 | ウィンドウの終了処理 |
| 4 | ID Stack Tool Window | 主機能 | ウィンドウの終了処理 |
| 5 | About Window | 主機能 | ウィンドウの終了処理 |
| 6 | Style Editor | 主機能 | ウィンドウの終了処理 |
| 10-22 | 各種ウィンドウ | 主機能 | ウィンドウの終了処理 |

## 機能種別

ウィンドウ管理 / UI構造制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (なし) | - | - | 引数なし | - |

### 入力データソース

- グローバルコンテキストの現在のウィンドウ（g.CurrentWindow）
- ウィンドウスタック（g.CurrentWindowStack）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (なし) | void | 戻り値なし |

### 出力先

- グローバルコンテキスト（ウィンドウスタックの更新、現在のウィンドウの復元）

## 処理フロー

### 処理シーケンス

```
1. 呼び出し回数の検証
   └─ End()が過剰に呼び出されていないか確認
2. 子ウィンドウチェック
   └─ 子ウィンドウに対してEnd()が直接呼び出されていないか確認
3. カラムの終了
   └─ DC.CurrentColumnsがある場合はEndColumns()を呼び出し
4. クリップ矩形のポップ
   └─ PopClipRect()を呼び出し
5. フォーカススコープのポップ
   └─ PopFocusScope()を呼び出し
6. ロギングの終了
   └─ ログウィンドウの場合はLogFinish()を呼び出し
7. エラーリカバリ
   └─ ConfigErrorRecoveryが有効な場合はスタック状態を復元
8. ウィンドウスタックからポップ
   └─ CurrentWindowStackからポップし、前のウィンドウを復元
```

### フローチャート

```mermaid
flowchart TD
    A[End開始] --> B{呼び出し回数チェック}
    B -->|過剰| C[エラー: End too many times]
    B -->|OK| D{子ウィンドウ?}
    D -->|Yes| E[エラー: Must call EndChild]
    D -->|No| F{カラムが開いている?}
    F -->|Yes| G[EndColumns]
    F -->|No| H[PopClipRect]
    G --> H
    H --> I[PopFocusScope]
    I --> J{ログウィンドウ?}
    J -->|Yes| K[LogFinish]
    J -->|No| L[エラーリカバリ]
    K --> L
    L --> M[ウィンドウスタックからポップ]
    M --> N[前のウィンドウを復元]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | Begin/Endペア | すべてのBegin()呼び出しに対してEnd()を呼び出す必要がある | 常時 |
| BR-002 | 子ウィンドウ禁止 | 子ウィンドウに対してはEndChild()を使用し、End()は使用しない | 子ウィンドウの場合 |
| BR-003 | スタック整合性 | End()呼び出し後、ウィンドウスタックは整合性のある状態に復元される | 常時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

なし（本機能はメモリ内のデータ構造のみを操作する）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション失敗 | End()が過剰に呼び出された場合 | Begin/Endの対応を確認する |
| - | アサーション失敗 | 子ウィンドウに対してEnd()を呼び出した場合 | EndChild()を使用する |

### リトライ仕様

なし

## トランザクション仕様

なし

## パフォーマンス要件

- 処理時間: 数マイクロ秒程度
- メモリ使用: スタック操作のみ

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

なし

## 備考

- Begin/Endは他のBeginXXX/EndXXXペアとは異なり、Beginがfalseを返してもEndを呼び出す必要がある
- ConfigErrorRecoveryが有効な場合、スタックの不整合を自動的に修復する

---

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

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

### 推奨読解順序

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

ImGuiWindowStackDataとウィンドウスタックの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiWindowStackData構造体定義 |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiContext::CurrentWindowStack |

**読解のコツ**: WindowStackDataにはウィンドウ参照と共に、復元用のバックアップ情報が格納されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | End関数宣言（436行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | End関数実装（8151-8203行目） |

**主要処理フロー**:
1. **8151-8154行目**: 関数開始、現在のウィンドウの取得
2. **8156-8161行目**: 呼び出し回数の検証
3. **8165-8166行目**: 子ウィンドウチェック
4. **8168-8173行目**: カラム終了、クリップ矩形ポップ
5. **8183-8185行目**: ロギング終了
6. **8198-8202行目**: エラーリカバリとスタックからのポップ

#### Step 3: エラーリカバリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | ErrorRecoveryTryToRecoverWindowState関数 |

**主要処理フロー**:
- スタックサイズの不整合を検出
- 自動的にスタックを復元

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

```
End()
    │
    ├─ EndColumns() [カラムが開いている場合]
    │
    ├─ PopClipRect() [SkipRefreshでない場合]
    │
    ├─ PopFocusScope()
    │
    ├─ EndDisabledOverrideReenable() [必要な場合]
    │
    ├─ LogFinish() [ログウィンドウの場合]
    │
    ├─ ErrorRecoveryTryToRecoverWindowState() [ConfigErrorRecovery有効時]
    │
    └─ SetCurrentWindow() [前のウィンドウを復元]
```

### データフロー図

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

g.CurrentWindow ──────────▶
g.CurrentWindowStack ─────▶  End()                   ──▶ スタック更新
                                │
                                ▼
                          クリーンアップ処理
                                │
                                ▼
                          g.CurrentWindow 復元 ─────▶ 前のウィンドウ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダ | API宣言 |
| imgui.cpp | `imgui.cpp` | ソース | End関数の実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダ | ImGuiWindowStackData構造体定義 |
