# 機能設計書 2-DestroyContext

## 概要

本ドキュメントはDear ImGuiライブラリのDestroyContext関数に関する機能設計書である。DestroyContextはImGuiコンテキストを破棄し、関連リソースを解放する終了処理関数である。

### 本機能の処理概要

DestroyContext関数は、CreateContextで作成されたImGuiContextを破棄し、使用していたすべてのリソース（メモリ、フォントアトラス、ウィンドウ情報等）を解放する機能を提供する。

**業務上の目的・背景**：ImGuiライブラリを使用したアプリケーションが終了する際、適切にリソースを解放する必要がある。メモリリークを防ぎ、クリーンなシャットダウンを実現するために、CreateContextで作成したコンテキストはDestroyContextで破棄する必要がある。また、複数コンテキストを使用している場合は、不要になったコンテキストを個別に破棄することも可能である。

**機能の利用シーン**：
- アプリケーション終了時のImGuiクリーンアップ処理
- 動的にコンテキストを作成・破棄するプラグインシステム
- テスト環境でのコンテキストリセット
- DLL/共有ライブラリのアンロード前処理

**主要な処理内容**：
1. 対象コンテキストの特定（引数NULLの場合は現在のコンテキスト）
2. 設定ファイル（.ini）の保存（設定が読み込まれていた場合）
3. フォントアトラスのクリーンアップ
4. すべてのウィンドウ、スタック、内部状態の解放
5. コンテキストフックの呼び出し（シャットダウン通知）
6. メモリの解放

**関連システム・外部連携**：
- プラットフォームバックエンド：DestroyContext前にバックエンドのシャットダウンを呼び出す必要がある
- レンダラーバックエンド：同様にレンダラーのシャットダウンを先に行う
- INI設定ファイル：設定の自動保存が行われる

**権限による制御**：特になし。ただし、DLL境界を跨いで使用している場合は、適切なコンテキストを指定する必要がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全ての画面のリソース解放処理 |

## 機能種別

終了処理 / リソース解放 / コンテキスト管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ctx | ImGuiContext* | No | 破棄するコンテキスト。NULLの場合は現在のコンテキストを破棄 | NULLまたは有効なImGuiContextポインタ |

### 入力データソース

- アプリケーションコード（オプショナル引数）
- GImGuiグローバル変数（引数がNULLの場合）

## 出力仕様

### 出力データ

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

### 出力先

- INI設定ファイル（設定が読み込まれていた場合、自動保存）
- GImGui（NULLに設定される場合がある）

## 処理フロー

### 処理シーケンス

```
1. 現在のコンテキストを保存
   └─ GetCurrentContext()で既存のコンテキストを取得

2. 対象コンテキストの特定
   └─ ctxがNULLの場合、現在のコンテキストを使用

3. 対象コンテキストを現在のコンテキストとして設定
   └─ SetCurrentContext(ctx)

4. シャットダウン処理（Shutdown関数）
   ├─ バックエンドシャットダウン確認
   ├─ フォントアトラスのクリーンアップ
   ├─ 設定ファイルの保存
   ├─ コンテキストフックの呼び出し
   └─ 内部状態のクリア

5. 元のコンテキストを復元（または NULL）
   └─ SetCurrentContext((prev_ctx != ctx) ? prev_ctx : NULL)

6. コンテキストメモリを解放
   └─ IM_DELETE(ctx)
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[現在のコンテキストを保存<br/>prev_ctx = GetCurrentContext]
    B --> C{ctx == NULL?}
    C -->|Yes| D[ctx = prev_ctx]
    C -->|No| E[ctxをそのまま使用]
    D --> F[SetCurrentContext ctx]
    E --> F
    F --> G[Shutdown 処理]
    G --> H{prev_ctx != ctx?}
    H -->|Yes| I[SetCurrentContext prev_ctx]
    H -->|No| J[SetCurrentContext NULL]
    I --> K[IM_DELETE ctx]
    J --> K
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 引数NULL時の動作 | ctxがNULLの場合、現在のコンテキストが破棄される | 引数がNULLの場合 |
| BR-02 | 設定の自動保存 | 設定が読み込まれていた場合、シャットダウン前に自動保存される | g.SettingsLoaded && g.IO.IniFilename != NULL |
| BR-03 | バックエンド確認 | バックエンドが先にシャットダウンされていることを確認（アサート） | 常に |
| BR-04 | コンテキスト復元 | 破棄対象と異なるコンテキストが現在だった場合、復元される | prev_ctx != ctx |

### 計算ロジック

特になし

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

該当なし（メモリ操作およびファイルI/Oのみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT_USER_ERROR | アサート失敗 | プラットフォームバックエンドが未シャットダウン | ImGui_ImplXXX_Shutdown()を先に呼び出す |
| IM_ASSERT_USER_ERROR | アサート失敗 | レンダラーバックエンドが未シャットダウン | ImGui_ImplXXX_Shutdown()を先に呼び出す |
| IM_ASSERT | アサート失敗 | コンテキスト二重破棄 | 既に破棄されたコンテキストを再度破棄しない |

### リトライ仕様

特になし

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

設定ファイル保存については、アトミック書き込みの保証はない

## パフォーマンス要件

- 終了処理のため、パフォーマンス要件は緩い
- 大量のウィンドウ/リソースがある場合、クリーンアップに時間がかかる可能性

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

- 設定ファイル（.ini）に機密情報が含まれる場合は注意が必要
- メモリ解放により、機密データがメモリ上から消去される

## 備考

- バージョン1.60以降、以前のShutdown()関数はDestroyContext()に置き換えられた
- CreateContext/DestroyContextのペアが必須

---

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

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

### 推奨読解順序

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

DestroyContextが解放するリソースを理解するため、ImGuiContextの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiContext構造体のメンバ（2189行目付近）。Windows、FontAtlases、各種スタック等 |

**読解のコツ**: 解放対象となるメンバを特定する:
- `ImVector<ImGuiWindow*> Windows` - ウィンドウリスト
- `ImVector<ImFontAtlas*> FontAtlases` - フォントアトラス
- `ImGuiStorage WindowsById` - ウィンドウID管理
- 各種スタック（ColorStack, StyleVarStack, FontStack等）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | 393行目: DestroyContextのAPI宣言 |
| 2-2 | imgui.cpp | `imgui.cpp` | 4087-4096行目: DestroyContext関数の実装 |

**主要処理フロー**:
1. **4089行目**: 現在のコンテキストを保存 `prev_ctx = GetCurrentContext()`
2. **4090-4091行目**: ctxがNULLの場合、現在のコンテキストを使用
3. **4092行目**: 対象コンテキストを設定 `SetCurrentContext(ctx)`
4. **4093行目**: シャットダウン処理 `Shutdown()`
5. **4094行目**: コンテキスト復元またはNULL設定
6. **4095行目**: メモリ解放 `IM_DELETE(ctx)`

#### Step 3: Shutdown処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | 4406-4500行目: Shutdown関数の実装 |

**主要処理フロー**:
- **4409-4410行目**: バックエンドシャットダウン確認
- **4413-4421行目**: フォントアトラスのクリーンアップ
- **4428-4430行目**: 設定ファイルの保存
- **4432行目**: シャットダウンフックの呼び出し
- **4435-4455行目**: ウィンドウ、スタック等のクリア

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

```
ImGui::DestroyContext(ctx)
    │
    ├─ ImGui::GetCurrentContext()
    │      └─ return GImGui
    │
    ├─ ImGui::SetCurrentContext(ctx)
    │      └─ GImGui = ctx
    │
    ├─ ImGui::Shutdown()
    │      ├─ UnregisterFontAtlas() [for each atlas]
    │      ├─ IM_DELETE(atlas) [if refcount == 0]
    │      ├─ SaveIniSettingsToDisk() [if settings loaded]
    │      ├─ CallContextHooks(ImGuiContextHookType_Shutdown)
    │      ├─ g.Windows.clear_delete()
    │      ├─ g.WindowsById.Clear()
    │      ├─ g.Viewports.clear_delete()
    │      └─ [各種スタック、テーブルのクリア]
    │
    ├─ ImGui::SetCurrentContext(prev_ctx or NULL)
    │
    └─ IM_DELETE(ctx)
```

### データフロー図

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

ctx (or NULL) ───────────▶ DestroyContext ──────────────▶ INI設定ファイル保存
       │                         │                          (条件付き)
       │                         │
       ▼                         ▼
 GImGui(現在の               Shutdown()で
 コンテキスト)               内部状態クリア
                                 │
                                 ▼
                            IM_DELETE(ctx)
                            メモリ解放
                                 │
                                 ▼
                            GImGui更新
                            (NULLまたはprev_ctx)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPI宣言（393行目） |
| imgui.cpp | `imgui.cpp` | ソース | DestroyContext実装（4087-4096行目） |
| imgui.cpp | `imgui.cpp` | ソース | Shutdown実装（4406-4500行目） |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiContext構造体定義（2189行目） |
