# 帳票設計書 2-ファイルログ出力

## 概要

本ドキュメントは、Dear ImGuiライブラリのファイルログ出力機能に関する帳票設計書である。GUIのテキスト出力をファイルにキャプチャしてログとして保存する機能について記述する。

### 本帳票の処理概要

ファイルログ出力機能は、ImGuiウィジェットから生成されるテキスト出力をファイルにキャプチャし、永続的に保存する機能である。

**業務上の目的・背景**：GUI開発において、アプリケーションの動作履歴を後から分析したり、テスト結果を記録したりする必要がある。ファイルログ出力機能により、GUIの状態やユーザー操作をファイルとして保存でき、オフラインでの分析や他者との共有が可能となる。また、自動テストの結果記録やバグレポートの添付資料としても活用できる。

**帳票の利用シーン**：開発者がウィンドウ構造やウィジェット状態を記録したい場合に、LogToFile関数を呼び出してログキャプチャを開始する。テスト自動化においては、特定の操作シーケンス後の状態をログファイルとして出力し、期待値との比較検証に使用される。LogButtons関数によりGUI上のボタンからも簡便にファイル出力を開始できる。

**主要な出力内容**：
1. ウィジェットのテキストラベル（Button、Text、TreeNodeなど）
2. ツリー構造のインデント（TreeDepthに応じた4スペースのインデント）
3. LogText関数で直接出力されたカスタムテキスト
4. ウィジェットの装飾テキスト（prefix/suffix）

**帳票の出力タイミング**：LogToFile関数が呼び出された時点からログキャプチャが開始され、LogFinish関数が呼び出されるとファイルがクローズされる。デフォルトではio.LogFilename（imgui_log.txt）に追記モードで出力される。

**帳票の利用者**：アプリケーション開発者、QAエンジニア、テスト自動化担当者、サポートエンジニア

## 帳票種別

ログ出力（テキストファイル形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | 任意のImGuiウィンドウ | - | LogToFile()関数呼び出し |
| - | デモウィンドウ | - | LogButtonsからの「Log To File」ボタン |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキストファイル |
| 用紙サイズ | N/A（ファイル出力） |
| 向き | N/A |
| ファイル名 | デフォルト: imgui_log.txt（io.LogFilenameで変更可能） |
| 出力方法 | ファイルへの追記書き込み |
| 文字コード | バイナリモード（ab）で出力、改行コードはシステム依存 |

### ファイル固有設定

| 項目 | 内容 |
|-----|------|
| オープンモード | "ab"（バイナリ追記モード） |
| デフォルトファイル名 | io.LogFilename（imgui_log.txt） |
| ファイルクローズ | LogFinish()呼び出し時 |

## 帳票レイアウト

### レイアウト概要

テキストベースのログ出力であり、階層構造をインデントで表現する。

```
[ウィンドウ/ウィジェットテキスト]
    [子ウィジェットテキスト（4スペースインデント）]
        [孫ウィジェット（8スペースインデント）]
[改行による区切り]
```

### 出力項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | テキスト内容 | ウィジェットが表示するテキスト | ImGui::LogRenderedText | プレーンテキスト |
| 2 | インデント | ツリー深度に応じた空白 | TreeDepth * 4 | スペース文字 |
| 3 | 改行 | 行の区切り | IM_NEWLINE | LF または CRLF |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| LogEnabled | ログ機能が有効であること | Yes |
| 有効なファイル名 | filenameまたはio.LogFilenameが設定されていること | Yes |
| ファイルオープン成功 | ImFileOpenが成功すること | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 描画順 | 昇順（ウィジェット描画順） |

### 改ページ条件

N/A（テキストファイルのため改ページ概念なし）

## データベース参照仕様

### 参照テーブル一覧

N/A（データベースは使用しない）

### 内部データ構造参照

| データ構造 | 用途 | アクセス方法 |
|-----------|------|-------------|
| ImGuiContext.LogFile | 出力先ファイルハンドル | g.LogFile |
| ImGuiContext.LogEnabled | ログ有効フラグ | g.LogEnabled |
| ImGuiContext.LogFlags | ログ種別フラグ | g.LogFlags |
| ImGuiContext.LogBuffer | 一時バッファ | g.LogBuffer |
| ImGuiIO.LogFilename | デフォルトファイル名 | g.IO.LogFilename |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| インデント幅 | TreeDepth * 4 | なし | スペース文字数 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[LogToFile呼び出し] --> B{既にログ有効?}
    B -->|Yes| Z[終了]
    B -->|No| C{ファイル名指定あり?}
    C -->|No| D[io.LogFilename使用]
    C -->|Yes| E[指定ファイル名使用]
    D --> F{ファイル名有効?}
    E --> F
    F -->|No| Z
    F -->|Yes| G[ImFileOpen実行]
    G --> H{オープン成功?}
    H -->|No| I[IM_ASSERT]
    I --> Z
    H -->|Yes| J[LogBegin実行]
    J --> K[ログキャプチャ開始]
    K --> L[ウィジェット描画]
    L --> M[LogRenderedText呼び出し]
    M --> N[テキストをファイルへ出力]
    N --> O{LogFinish呼び出し?}
    O -->|No| L
    O -->|Yes| P[ImFileClose実行]
    P --> Q[ログ状態リセット]
    Q --> Z
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 既にログ有効 | LogToFile呼び出し時に既にログが有効 | なし（早期リターン） | 既存ログセッションを終了後に再開 |
| ファイル名未指定 | filename引数がNULLかつio.LogFilenameもNULL/空 | なし（早期リターン） | 有効なファイル名を指定 |
| ファイルオープン失敗 | ImFileOpenがNULLを返す | IM_ASSERT(0) | ファイルパス・権限を確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 無制限 |
| 目標出力時間 | I/O依存 |
| 同時出力数上限 | 1（同時に1つのログセッションのみ） |

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

- 機密情報がログファイルに含まれる可能性があるため、ファイルのアクセス権限管理に注意
- ログファイルの出力先ディレクトリのセキュリティを確認
- 本番環境での長期間のログ記録はディスク容量に注意

## 備考

- バイナリモード（"ab"）でオープンすることで、プラットフォーム間で一貫した改行処理を実現
- 追記モードのため、既存ファイルがあれば末尾に追加される
- auto_open_depth引数により、ツリーノードの自動展開深度を制御可能（-1でデフォルト値使用）

---

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

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

### 推奨読解順序

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

まず、ログ機能で使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | 959-965行目: LogToFile等のAPI宣言を確認 |
| 1-2 | imgui.h | `imgui.h` | io.LogFilenameメンバの宣言を確認 |
| 1-3 | imgui_internal.h | `imgui_internal.h` | ImGuiLogFlags列挙型を確認 |

**読解のコツ**: imgui.hの関数宣言コメントでデフォルトファイル名の仕様を把握する。

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

処理の起点となる関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.cpp | `imgui.cpp` | 15188-15210行目: LogToFile関数の実装 |

**主要処理フロー**:
1. **15190-15192行目**: 既にログ有効なら早期リターン
2. **15197-15198行目**: ファイル名の決定（引数優先、なければio.LogFilename）
3. **15199-15200行目**: ファイル名が無効なら早期リターン
4. **15201行目**: ImFileOpenでファイルオープン（"ab"モード）
5. **15202-15206行目**: オープン失敗時はIM_ASSERTして早期リターン
6. **15208行目**: LogBegin関数でログセッション開始
7. **15209行目**: ファイルハンドルをg.LogFileに設定

#### Step 3: ファイルI/O処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | 15229-15261行目: LogFinish関数 |
| 3-2 | imgui.cpp | `imgui.cpp` | 15243-15245行目: ImFileCloseによるファイルクローズ |

**主要処理フロー**:
- **15244行目**: ImFileCloseでファイルをクローズ

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

```
LogToFile(auto_open_depth, filename)
    │
    ├─ [ファイル名決定]
    │      └─ filename ? filename : g.IO.LogFilename
    │
    ├─ ImFileOpen(filename, "ab")
    │
    ├─ LogBegin(ImGuiLogFlags_OutputFile, auto_open_depth)
    │      ├─ g.LogEnabled = true
    │      ├─ g.LogFlags = flags
    │      └─ g.LogDepthRef = window->DC.TreeDepth
    │
    └─ g.LogFile = f
           │
           └─ [ウィジェット描画時]
                  │
                  └─ LogRenderedText(ref_pos, text, text_end)
                         │
                         └─ LogText(fmt, ...)
                                │
                                └─ LogTextV(g, fmt, args)
                                       │
                                       └─ fprintf(g.LogFile, ...)

LogFinish()
    │
    ├─ LogText(IM_NEWLINE)
    ├─ ImFileClose(g.LogFile)
    └─ g.LogEnabled = false
```

### データフロー図

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

LogToFile(filename) ──▶ ImFileOpen("ab")
                              │
                              ▼
                        LogBegin()
                              │
                              ▼
ウィジェット描画 ─────────▶ LogRenderedText()
                              │
                              ▼
                        LogTextV() ────────────────▶ ファイル書き込み
                              │
                              ▼
LogFinish() ──────────▶ ImFileClose() ─────────────▶ [ファイル完成]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | 公開API宣言（LogToFile等） |
| imgui.cpp | `imgui.cpp` | ソース | ログ機能の実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部データ構造定義、ImFileOpen/Close宣言 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | LogButtons関数の使用例 |
