# 機能設計書 257-imgui_impl_sdl3

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるSDL3プラットフォームバックエンド（imgui_impl_sdl3）の設計仕様を定義する。

### 本機能の処理概要

imgui_impl_sdl3は、SDL3ライブラリを使用してDear ImGuiにプラットフォーム機能を提供するクロスプラットフォームバックエンドモジュールである。SDL2バックエンドの後継として、SDL3の新しいAPIに対応し、マウス、キーボード、ゲームパッド入力の処理、マウスカーソル形状の制御、クリップボードアクセス、IMEサポートなどを実装する。

**業務上の目的・背景**：
SDL3（Simple DirectMedia Layer 3）は、SDL2の後継バージョンであり、API設計の改善、GPU抽象化レイヤー（SDL_GPU）の追加、より良いプラットフォームサポートを提供する。本バックエンドは、SDL3を使用する最新アプリケーションにDear ImGuiを統合するための標準的な方法を提供する。

**機能の利用シーン**：
- SDL3を使用する新規ゲーム開発
- SDL_GPUを使用するグラフィックスアプリケーション
- SDL2からSDL3への移行プロジェクト
- クロスプラットフォームツール開発

**主要な処理内容**：
1. バックエンドの初期化（ImGui_ImplSDL3_InitFor*）
2. 毎フレームの更新処理（ImGui_ImplSDL3_NewFrame）
3. SDLイベント処理（ImGui_ImplSDL3_ProcessEvent）
4. マウスカーソル形状の制御
5. ゲームパッド入力の処理（SDL_Gamepad）
6. クリップボード/IMEサポート
7. マウスキャプチャモード制御

**関連システム・外部連携**：
- SDL3ライブラリ
- 描画バックエンド（SDL_GPU、SDL_Renderer、OpenGL、Vulkan、DirectX、Metal等）と併用

**権限による制御**：
特別な権限は不要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全てのImGuiウィンドウの基盤として機能 |

## 機能種別

プラットフォームバックエンド

## 入力仕様

### 入力パラメータ

#### ImGui_ImplSDL3_InitForOpenGL

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| window | SDL_Window* | Yes | SDLウィンドウハンドル | 有効なウィンドウ |
| sdl_gl_context | void* | Yes | OpenGLコンテキスト | - |

#### ImGui_ImplSDL3_ProcessEvent

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| event | const SDL_Event* | Yes | SDLイベント | - |

### 入力データソース

- SDL_Event（イベント処理）
- SDL_GetPerformanceCounter()（時間計測）
- SDL_GetGamepadAxis()/SDL_GetGamepadButton()（ゲームパッド状態）
- SDL_GetClipboardText()/SDL_SetClipboardText()（クリップボード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ImGuiIO.DisplaySize | ImVec2 | ウィンドウサイズ |
| ImGuiIO.DisplayFramebufferScale | ImVec2 | フレームバッファスケール |
| ImGuiIO.DeltaTime | float | フレーム間隔 |
| ImGuiIO（入力イベント） | - | マウス/キーボード/ゲームパッドイベント |

### 出力先

ImGuiIO構造体への入力イベント登録

## 処理フロー

### 処理シーケンス

```
1. 初期化（ImGui_ImplSDL3_InitFor*）
   ├─ バックエンドデータ構造の確保
   ├─ ImGuiIO設定（バックエンド名、フラグ）
   ├─ プラットフォーム検出（マウスキャプチャ対応確認）
   ├─ クリップボード/IMEハンドラ設定
   ├─ ゲームパッドモード設定
   ├─ マウスカーソル作成
   └─ プラットフォーム固有設定（WindowID取得等）
2. イベント処理（ImGui_ImplSDL3_ProcessEvent）
   ├─ SDL_EVENT_MOUSE_MOTIONイベント処理
   ├─ SDL_EVENT_MOUSE_WHEELイベント処理
   ├─ SDL_EVENT_MOUSE_BUTTON_DOWN/UPイベント処理
   ├─ SDL_EVENT_TEXT_INPUTイベント処理
   ├─ SDL_EVENT_KEY_DOWN/UPイベント処理
   ├─ SDL_EVENT_WINDOW_*イベント処理
   └─ SDL_EVENT_GAMEPAD_*イベント処理
3. フレーム更新（ImGui_ImplSDL3_NewFrame）
   ├─ ウィンドウサイズ・フレームバッファスケール取得
   ├─ デルタタイム計算
   ├─ マウスデータ更新（キャプチャ含む）
   ├─ マウスカーソル形状更新
   ├─ IME更新
   └─ ゲームパッド状態更新
4. 終了処理（ImGui_ImplSDL3_Shutdown）
   ├─ クリップボードデータ解放
   ├─ マウスカーソル破棄
   ├─ ゲームパッドクローズ
   └─ バックエンドデータ解放
```

### フローチャート

```mermaid
flowchart TD
    A[ImGui_ImplSDL3_Init] --> B[SDL_PollEvent]
    B --> C{イベントあり?}
    C -->|Yes| D[ImGui_ImplSDL3_ProcessEvent]
    C -->|No| E[ImGui_ImplSDL3_NewFrame]
    D --> C
    E --> F[ImGui処理]
    F --> G[描画]
    G --> B
    H[Shutdown] --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-257-01 | レンダラー併用必須 | 描画バックエンドと併用必須 | 常に適用 |
| BR-257-02 | SDL初期化必須 | SDL_Init()後に使用 | 初期化時 |
| BR-257-03 | イベント処理必須 | ProcessEventをSDLイベントに対して呼び出す | メインループ |
| BR-257-04 | ゲームパッドモード | AutoFirst/AutoAll/Manualから選択 | ゲームパッド使用時 |
| BR-257-05 | マウスキャプチャ | X11ではドラッグ後に有効化 | X11環境 |

### 計算ロジック

**フレームバッファスケール計算**:
```cpp
// macOSの場合
float fb_scale_x = SDL_GetWindowDisplayScale(window);
float fb_scale_y = fb_scale_x;

// その他の場合
fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f;
fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f;
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------||
| - | 時間逆行 | SDL_GetPerformanceCounter()が単調増加しない | 最小増分で対応 |
| - | クリップボード取得失敗 | クリップボードが空またはテキストでない | NULLを返却 |

### リトライ仕様

リトライ機能なし。

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

トランザクション管理なし

## パフォーマンス要件

- ProcessEvent: O(1)（イベント処理）
- NewFrame: O(1)（固定時間処理）
- SDL_GetGlobalMouseState()はX11で低速の可能性があるため最適化

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

- クリップボード操作はSDL経由で安全に処理
- IME入力はSDL_SetTextInputArea経由で位置指定

## 備考

- SDL3はSDL2からのAPIリファクタリングを含む（SDL_GetClipboardText()のメモリ管理変更など）
- SDL_GPUバックエンドとの併用に対応（ImGui_ImplSDL3_InitForSDLGPU）
- macOSではSDL_GetWindowDisplayScale()を使用してより信頼性の高いスケール取得
- Emscripten/Android/iOSではSDL_CaptureMouse()非対応

---

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

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

### 推奨読解順序

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

バックエンドデータ構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_sdl3.cpp | `backends/imgui_impl_sdl3.cpp` | ImGui_ImplSDL3_Data構造体（107-136行目） |

**読解のコツ**: ゲームパッドはImVector<SDL_Gamepad*>で管理、モードはImGui_ImplSDL3_GamepadMode列挙型で指定。SDL2との違いとしてImeWindow/ImeData/ImeDirtyフィールドが追加されている。

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

初期化関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_sdl3.h | `backends/imgui_impl_sdl3.h` | 関数宣言（31-40行目） |
| 2-2 | imgui_impl_sdl3.cpp | `backends/imgui_impl_sdl3.cpp` | ImGui_ImplSDL3_Init実装（496-573行目） |

**主要処理フロー**:
1. **498-500行目**: ImGuiIOとバージョン確認
2. **507-513行目**: バックエンドデータ確保とフラグ設定
3. **519-532行目**: マウスキャプチャ対応プラットフォーム検出
4. **534-538行目**: クリップボード/IMEハンドラ設定
5. **544-555行目**: マウスカーソル作成

#### Step 3: イベント処理を理解する

ProcessEvent関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_sdl3.cpp | `backends/imgui_impl_sdl3.cpp` | ImGui_ImplSDL3_ProcessEvent実装（380-483行目） |

**主要処理フロー**:
- **388-396行目**: SDL_EVENT_MOUSE_MOTIONイベント処理
- **408-425行目**: SDL_EVENT_MOUSE_BUTTON_DOWN/UPイベント処理
- **433-445行目**: SDL_EVENT_KEY_DOWN/KEYUPイベント処理
- **446-472行目**: SDL_EVENT_WINDOW_*イベント処理

#### Step 4: フレーム更新処理を理解する

NewFrame関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_sdl3.cpp | `backends/imgui_impl_sdl3.cpp` | ImGui_ImplSDL3_NewFrame実装（848-879行目） |

**主要処理フロー**:
- **855行目**: ウィンドウサイズ・フレームバッファスケール取得
- **859-864行目**: デルタタイム計算
- **873行目**: マウスデータ更新
- **874行目**: マウスカーソル更新
- **875行目**: IME更新
- **878行目**: ゲームパッド更新

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

```
アプリケーション
    │
    ├─ SDL_Init()
    │
    ├─ ImGui_ImplSDL3_InitForOpenGL(window, gl_context)
    │      ├─ ImGui_ImplSDL3_Init
    │      │      ├─ プラットフォーム検出
    │      │      ├─ クリップボード/IMEハンドラ設定
    │      │      └─ マウスカーソル作成
    │      └─ ゲームパッドモード設定
    │
    ├─ メインループ
    │      ├─ SDL_PollEvent(&event)
    │      │      └─ ImGui_ImplSDL3_ProcessEvent(&event)
    │      │              ├─ io.AddMousePosEvent
    │      │              ├─ io.AddMouseButtonEvent
    │      │              ├─ io.AddKeyEvent
    │      │              └─ io.AddInputCharactersUTF8
    │      │
    │      └─ ImGui_ImplSDL3_NewFrame
    │              ├─ ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale
    │              ├─ ImGui_ImplSDL3_UpdateMouseData
    │              ├─ ImGui_ImplSDL3_UpdateMouseCursor
    │              ├─ ImGui_ImplSDL3_UpdateIme
    │              └─ ImGui_ImplSDL3_UpdateGamepads
    │
    └─ ImGui_ImplSDL3_Shutdown
           ├─ クリップボードデータ解放
           ├─ カーソル破棄
           └─ ゲームパッドクローズ
```

### データフロー図

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

SDL_Event ────────────────▶ ProcessEvent ─────────▶ ImGuiIO入力イベント
SDL_GetPerformanceCounter() ▶ NewFrame ───────────▶ ImGuiIO.DeltaTime
SDL_GetWindowSize() ───────▶ NewFrame ───────────▶ ImGuiIO.DisplaySize
SDL_GetGamepadAxis() ──────▶ UpdateGamepads ─────▶ ImGuiIO入力イベント
SDL_GetClipboardText() ────▶ Platform_GetClipboard ▶ クリップボードテキスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_sdl3.h | `backends/imgui_impl_sdl3.h` | ヘッダー | 関数宣言 |
| imgui_impl_sdl3.cpp | `backends/imgui_impl_sdl3.cpp` | ソース | 実装 |
| imgui.h | `imgui.h` | ヘッダー | ImGuiIO定義 |
