# 機能設計書 8-NewFrame

## 概要

本ドキュメントはDear ImGuiライブラリのNewFrame関数に関する機能設計書である。NewFrameは新しいImGuiフレームを開始し、UI描画コマンドの受付を開始する関数である。

### 本機能の処理概要

NewFrame関数は、新しいImGuiフレームの開始を宣言し、Render()またはEndFrame()が呼ばれるまでの間、UIコマンド（ウィジェット呼び出し等）を受け付ける状態にする。この関数はImGuiのメインループで毎フレーム呼び出される中核的な関数である。

**業務上の目的・背景**：ImGuiはImmediate Mode GUIライブラリであり、毎フレームUIを再構築する設計となっている。NewFrameはそのフレームサイクルの開始点であり、入力処理、時間管理、内部状態のリセット/更新を行う。バックエンドからの入力データ（io.MousePos, io.DeltaTime等）はこの関数が呼ばれる前に設定されている必要がある。

**機能の利用シーン**：
- メインループの各フレーム開始時
- バックエンドのNewFrame関数呼び出し後
- 入力データ設定完了後

**主要な処理内容**：
1. コンテキスト存在確認
2. コンテキストフック呼び出し（NewFramePre）
3. エラーチェック（サニティチェック）
4. 設定の読み込み/保存タイミング管理
5. フレームカウント・時間の更新
6. フレームレート計算
7. 入力イベント処理
8. ビューポート更新
9. テクスチャ更新
10. フォント更新
11. 各種内部状態のリセット/更新

**関連システム・外部連携**：
- プラットフォームバックエンド：ImGui_ImplXXX_NewFrame()を先に呼び出す
- レンダラーバックエンド：ImGui_ImplXXX_NewFrame()を先に呼び出す
- INI設定ファイル：初回フレームでの読み込み、定期的な保存

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全ての画面の前提となるフレーム開始処理 |

## 機能種別

フレーム管理 / 初期化処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- ImGuiIO構造体（事前に設定）：DeltaTime, MousePos, MouseDown[], KeysData[]等
- GImGuiグローバル変数（現在のコンテキスト）

## 出力仕様

### 出力データ

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

### 出力先

- コンテキスト内部状態の更新
- DrawData準備状態の設定

## 処理フロー

### 処理シーケンス

```
1. コンテキスト存在確認
   └─ IM_ASSERTでGImGui != NULLを確認

2. 削除保留フックの除去
   └─ PendingRemoval_タイプのフックを削除

3. コンテキストフック呼び出し
   └─ CallContextHooks(ImGuiContextHookType_NewFramePre)

4. エラーチェック
   └─ ErrorCheckNewFrameSanityChecks()

5. 設定の読み込み/保存
   └─ UpdateSettings()

6. フレームカウント・時間更新
   ├─ g.Time += g.IO.DeltaTime
   ├─ g.FrameCount += 1
   └─ フレームレート計算

7. 入力イベント処理
   └─ UpdateInputEvents()

8. ビューポート更新
   └─ UpdateViewportsNewFrame()

9. テクスチャ更新
   └─ UpdateTexturesNewFrame()

10. フォント更新
    ├─ SetupDrawListSharedData()
    └─ UpdateFontsNewFrame()

11. 内部状態更新
    ├─ WithinFrameScope = true
    ├─ DrawData無効化
    ├─ HoveredId/ActiveId更新
    └─ ナビゲーション状態更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{GImGui != NULL?}
    B -->|Yes| C[フック呼び出し NewFramePre]
    B -->|No| D[アサート失敗]
    C --> E[エラーチェック]
    E --> F[設定読み込み/保存]
    F --> G[時間・フレームカウント更新]
    G --> H[入力イベント処理]
    H --> I[ビューポート更新]
    I --> J[テクスチャ更新]
    J --> K[フォント更新]
    K --> L[内部状態更新]
    L --> M[WithinFrameScope = true]
    M --> N[終了]
    D --> O[プログラム停止]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | コンテキスト必須 | CreateContextが呼ばれていない場合、アサート失敗 | GImGui == NULL |
| BR-02 | バックエンド先行 | プラットフォーム/レンダラーバックエンドのNewFrameを先に呼び出す | 常に |
| BR-03 | フレームスコープ | NewFrame後、EndFrame/Renderまでの間WithinFrameScopeがtrue | フレーム中 |
| BR-04 | 入力設定タイミング | io.DeltaTime等はNewFrame呼び出し前に設定 | 常に |

### 計算ロジック

フレームレート計算:
```cpp
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / g.FramerateSecPerFrameCount);
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | アサート失敗 | コンテキストが存在しない | CreateContext()を呼び出す |
| IM_ASSERT | アサート失敗 | io.DeltaTimeが0以下 | 正の値を設定 |
| IM_ASSERT | アサート失敗 | io.DisplaySizeが無効 | 有効なサイズを設定 |

### リトライ仕様

特になし

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

該当なし

## パフォーマンス要件

- 毎フレーム呼び出されるため、効率的な実装が必要
- 多数の内部状態更新を行うが、通常は1ms未満で完了

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

- 特になし

## 備考

- NewFrameとEndFrame/Renderは必ずペアで呼び出す
- 描画をスキップする場合でも、NewFrameを呼んだらEndFrame/Renderを呼ぶ必要がある
- 初回のNewFrame呼び出しでINI設定が読み込まれる

---

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

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

### 推奨読解順序

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

NewFrameで更新される主要なコンテキストメンバを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_internal.h | `imgui_internal.h` | ImGuiContext構造体: FrameCount, Time, WithinFrameScope等 |

**読解のコツ**: 以下のメンバに注目:
- `bool WithinFrameScope` - NewFrame/EndFrame間のスコープフラグ
- `int FrameCount` - フレームカウンタ
- `double Time` - 経過時間
- `float Framerate` - 計算されたフレームレート

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

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

**主要処理フロー**:
1. **5455行目**: コンテキスト確認
2. **5458-5462行目**: 削除保留フックの除去
3. **5464行目**: NewFramePreフック呼び出し
4. **5467行目**: サニティチェック
5. **5470行目**: 設定更新
6. **5472-5483行目**: 時間・フレームカウント・フレームレート更新
7. **5485-5487行目**: 入力イベント処理
8. **5489-5497行目**: ビューポート・テクスチャ・フォント更新
9. **5499行目**: WithinFrameScope = true

#### Step 3: 関連する内部関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | ErrorCheckNewFrameSanityChecks() - 入力値の検証 |
| 3-2 | imgui.cpp | `imgui.cpp` | UpdateSettings() - INI設定の管理 |
| 3-3 | imgui.cpp | `imgui.cpp` | UpdateInputEvents() - 入力イベント処理 |

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

```
ImGui::NewFrame()
    │
    ├─ CallContextHooks(ImGuiContextHookType_NewFramePre)
    │
    ├─ ErrorCheckNewFrameSanityChecks()
    │
    ├─ UpdateSettings()
    │      └─ LoadIniSettingsFromDisk() [初回]
    │
    ├─ UpdateInputEvents()
    │
    ├─ UpdateViewportsNewFrame()
    │
    ├─ UpdateTexturesNewFrame()
    │
    ├─ SetupDrawListSharedData()
    │
    └─ UpdateFontsNewFrame()
```

### データフロー図

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

io.DeltaTime ─────────▶ NewFrame() ───────────────────▶ 更新されたコンテキスト
io.MousePos                  │                           - g.FrameCount++
io.KeysData[]                │                           - g.Time更新
                             ▼                           - WithinFrameScope=true
                      フレーム開始                        - DrawData無効化
                      内部状態更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPI宣言（401行目） |
| imgui.cpp | `imgui.cpp` | ソース | 実装（5453-5600行目） |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | ImGuiContext構造体定義 |
