# 機能設計書 260-imgui_impl_android

## 概要

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

### 本機能の処理概要

imgui_impl_androidは、Android NDK（Native Development Kit）を使用してDear ImGuiにプラットフォーム機能を提供するネイティブバックエンドモジュールである。キーボード入力、マウス/タッチ/ペン入力の処理を実装するが、機能は限定的であり、より多機能なSDLやGLFWバックエンドの使用が推奨される。

**業務上の目的・背景**：
AndroidのNative Activityを使用するアプリケーションにおいて、Dear ImGuiを統合するための基本的な方法を提供する。OpenGL ES 3との併用を想定している。

**機能の利用シーン**：
- Android NDKベースのネイティブアプリケーション
- OpenGL ES 3を使用するAndroidゲーム
- シンプルなデバッグUI/ツール

**主要な処理内容**：
1. バックエンドの初期化（ImGui_ImplAndroid_Init）
2. 毎フレームの更新処理（ImGui_ImplAndroid_NewFrame）
3. 入力イベント処理（ImGui_ImplAndroid_HandleInputEvent）
4. キーボード入力処理（AINPUT_EVENT_TYPE_KEY）
5. モーション入力処理（AINPUT_EVENT_TYPE_MOTION）

**関連システム・外部連携**：
- Android NDK
- OpenGL ES 3描画バックエンド（imgui_impl_opengl3）と併用

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

#### ImGui_ImplAndroid_Init

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| window | ANativeWindow* | Yes | Androidネイティブウィンドウ | 有効なウィンドウ |

#### ImGui_ImplAndroid_HandleInputEvent

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input_event | const AInputEvent* | Yes | Android入力イベント | - |

### 入力データソース

- AInputEvent（キーボード/モーションイベント）
- clock_gettime(CLOCK_MONOTONIC)（時間計測）
- ANativeWindow_getWidth()/ANativeWindow_getHeight()（ウィンドウサイズ）

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 初期化（ImGui_ImplAndroid_Init）
   ├─ ウィンドウハンドル保存
   ├─ 時間変数初期化
   └─ ImGuiIO設定（バックエンド名）
2. 入力イベント処理（ImGui_ImplAndroid_HandleInputEvent）
   ├─ AINPUT_EVENT_TYPE_KEY処理
   │      ├─ 修飾キー状態取得
   │      ├─ キーコード変換
   │      └─ キーイベント登録
   └─ AINPUT_EVENT_TYPE_MOTION処理
          ├─ ツールタイプ判定（マウス/ペン/タッチ）
          ├─ マウスソース設定
          ├─ ACTION_DOWN/UP処理
          ├─ BUTTON_PRESS/RELEASE処理
          ├─ HOVER_MOVE/MOVE処理
          └─ SCROLL処理
3. フレーム更新（ImGui_ImplAndroid_NewFrame）
   ├─ ウィンドウサイズ取得
   ├─ DisplaySize設定
   ├─ DisplayFramebufferScale計算
   └─ デルタタイム計算
4. 終了処理（ImGui_ImplAndroid_Shutdown）
   └─ バックエンド名クリア
```

### フローチャート

```mermaid
flowchart TD
    A[ImGui_ImplAndroid_Init] --> B[android_main ループ]
    B --> C{入力イベント?}
    C -->|Yes| D[ImGui_ImplAndroid_HandleInputEvent]
    C -->|No| E[ImGui_ImplAndroid_NewFrame]
    D --> B
    E --> F[ImGui処理]
    F --> G[描画]
    G --> B
    H[Shutdown] --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-260-01 | レンダラー併用必須 | OpenGL ES 3描画バックエンドと併用必須 | 常に適用 |
| BR-260-02 | NDKアプリ必須 | Native Activity/GameActivityで使用 | 常に適用 |
| BR-260-03 | SDL/GLFW推奨 | より多機能なバックエンドを推奨 | 常に |
| BR-260-04 | イベント処理必須 | HandleInputEventを適切に呼び出す | メインループ |

### 計算ロジック

**デルタタイム計算**:
```cpp
struct timespec current_timespec;
clock_gettime(CLOCK_MONOTONIC, &current_timespec);
double current_time = (double)(current_timespec.tv_sec) + (current_timespec.tv_nsec / 1000000000.0);
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------||
| - | 不明イベント | サポート外イベントタイプ | 0を返却 |
| - | キーボード表示 | オンスクリーンキーボード | アプリ側で対応必要 |

### リトライ仕様

リトライ機能なし。

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

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

## パフォーマンス要件

- HandleInputEvent: O(1)（イベント処理）
- NewFrame: O(1)（固定時間処理）

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

- クリップボードサポートなし
- 入力処理はAndroid NDK経由で実行

## 備考

- クリップボード非対応
- ゲームパッド非対応
- マウスカーソル形状変更非対応
- オンスクリーンキーボードはアプリ側で有効化が必要（issue #3446）
- Unicode文字入力はアプリ側で対応が必要（issue #3446）
- より多機能なSDL/GLFWバックエンドの使用を推奨

---

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

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

### 推奨読解順序

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

グローバル変数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_android.cpp | `backends/imgui_impl_android.cpp` | グローバル変数（42-44行目） |

**読解のコツ**: Androidバックエンドは状態をグローバル変数で管理するシンプルな構造。g_Time、g_Window、g_LogTagの3つのみ。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_android.h | `backends/imgui_impl_android.h` | 関数宣言（32-35行目） |
| 2-2 | imgui_impl_android.cpp | `backends/imgui_impl_android.cpp` | ImGui_ImplAndroid_Init実装（264-276行目） |

**主要処理フロー**:
1. **266行目**: バージョン確認
2. **268-269行目**: ウィンドウ・時間変数初期化
3. **272-273行目**: ImGuiIO設定（バックエンド名）

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_android.cpp | `backends/imgui_impl_android.cpp` | ImGui_ImplAndroid_HandleInputEvent実装（159-262行目） |

**主要処理フロー**:
- **165-198行目**: AINPUT_EVENT_TYPE_KEY処理
- **199-256行目**: AINPUT_EVENT_TYPE_MOTION処理
- **205-218行目**: ツールタイプによるマウスソース判定
- **220-234行目**: ACTION_DOWN/UP処理
- **236-244行目**: BUTTON_PRESS/RELEASE処理

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_android.cpp | `backends/imgui_impl_android.cpp` | ImGui_ImplAndroid_NewFrame実装（284-304行目） |

**主要処理フロー**:
- **288-296行目**: ウィンドウサイズ・フレームバッファスケール取得
- **298-303行目**: デルタタイム計算

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

```
android_main
    │
    ├─ ANativeWindow取得
    │
    ├─ ImGui_ImplAndroid_Init(window)
    │      ├─ g_Window = window
    │      ├─ g_Time = 0.0
    │      └─ io.BackendPlatformName設定
    │
    ├─ メインループ
    │      ├─ ALooper_pollAll
    │      │      └─ android_app_read_cmd
    │      │
    │      ├─ 入力イベント処理
    │      │      └─ ImGui_ImplAndroid_HandleInputEvent
    │      │              ├─ io.AddKeyEvent
    │      │              ├─ io.AddMouseSourceEvent
    │      │              ├─ io.AddMousePosEvent
    │      │              ├─ io.AddMouseButtonEvent
    │      │              └─ io.AddMouseWheelEvent
    │      │
    │      └─ ImGui_ImplAndroid_NewFrame
    │              ├─ ANativeWindow_getWidth/Height
    │              ├─ io.DisplaySize設定
    │              ├─ io.DisplayFramebufferScale設定
    │              └─ io.DeltaTime計算
    │
    └─ ImGui_ImplAndroid_Shutdown
           └─ io.BackendPlatformName = nullptr
```

### データフロー図

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

AInputEvent ────────────────▶ HandleInputEvent ──────▶ ImGuiIO入力イベント
clock_gettime(CLOCK_MONOTONIC) ▶ NewFrame ──────────▶ ImGuiIO.DeltaTime
ANativeWindow_getWidth() ───▶ NewFrame ──────────────▶ ImGuiIO.DisplaySize
ANativeWindow_getHeight() ──▶ NewFrame ──────────────▶ ImGuiIO.DisplaySize
AMotionEvent_getToolType() ─▶ HandleInputEvent ──────▶ ImGuiMouseSource
```

### 関連ファイル一覧

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