# 機能設計書 231-IsKeyReleased

## 概要

本ドキュメントは、ImGuiライブラリにおけるキーボード入力判定機能「IsKeyReleased」の設計仕様を定義する。

### 本機能の処理概要

IsKeyReleased関数は、指定されたキーが離された瞬間（Down状態から!Down状態への遷移）を検出する機能である。キーリリースイベントの検出は、キーボードショートカットの終了処理やトグル動作の実装に不可欠な機能を提供する。

**業務上の目的・背景**：GUIアプリケーションでは、キーが押された瞬間だけでなく、離された瞬間を検出する必要がある場面が多い。例えば、Shiftキーを押している間だけ特定のモードを有効にし、離した瞬間に元に戻すといった操作や、キー入力のホールド時間に応じた処理の終了判定などに使用される。この機能により、ユーザーの意図したタイミングでの処理制御が可能となる。

**機能の利用シーン**：
- モディファイアキー（Ctrl/Shift/Alt）の解除検出
- ゲームにおけるキャラクター移動の停止判定
- 押しっぱなし操作モードの終了判定
- キーリピート機能のリセットタイミング検出
- 連続入力防止のためのキー状態監視

**主要な処理内容**：
1. キーデータの取得（GetKeyData関数によるImGuiKeyData構造体の取得）
2. 前フレームでキーが押されていたかの確認（DownDurationPrev >= 0.0f）
3. 現在フレームでキーが離されているかの確認（Down == false）
4. キーオーナーシップの検証（TestKeyOwner関数による所有権チェック）
5. 全条件を満たした場合にtrueを返却

**関連システム・外部連携**：ImGuiIO構造体を介してバックエンドからキー入力情報を受け取り、キーオーナーシップシステム（内部）と連携してキーの所有権を管理する。

**権限による制御**：キーオーナーシップ機能により、特定のウィジェットがキー入力を専有している場合、他のコンポーネントからのIsKeyReleased呼び出しはfalseを返す。owner_idパラメータを指定することで、特定のオーナーに対してのみキーリリースを検出できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | Inputs | 参照画面 | キーボード入力判定のデモ表示 |

## 機能種別

入力判定処理 / 状態監視

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| key | ImGuiKey | Yes | 判定対象のキー（ImGuiKey_A〜ImGuiKey_Zなど） | IsNamedKey()でNamed Keyであることを検証 |
| owner_id | ImGuiID | No | キーオーナーID（内部API版のみ、デフォルトはImGuiKeyOwner_Any） | なし |

### 入力データソース

- ImGuiIO.KeysData配列：各キーの状態情報（ImGuiKeyData構造体）
- ImGuiKeyOwnerData：キーオーナーシップ情報（内部データ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | キーが離された瞬間の場合true、それ以外はfalse |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. パブリックAPI呼び出し（IsKeyReleased(key)）
   └─ owner_idをImGuiKeyOwner_Anyとして内部API版を呼び出し

2. キーデータの取得
   └─ GetKeyData(key)でImGuiKeyData構造体を取得

3. 前フレーム状態の確認
   └─ DownDurationPrev < 0.0fの場合、前フレームでキーが押されていなかったためfalseを返却

4. 現在フレーム状態の確認
   └─ Down == trueの場合、現在もキーが押されているためfalseを返却

5. キーオーナーシップの検証
   └─ TestKeyOwner(key, owner_id)でキーの所有権を確認、失敗時はfalseを返却

6. 結果の返却
   └─ 全条件を満たした場合trueを返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: IsKeyReleased] --> B[GetKeyData でキーデータ取得]
    B --> C{DownDurationPrev < 0.0f?}
    C -->|Yes| D[return false<br/>前フレームで押されていない]
    C -->|No| E{Down == true?}
    E -->|Yes| F[return false<br/>現在も押されている]
    E -->|No| G{TestKeyOwner 成功?}
    G -->|No| H[return false<br/>オーナーシップ失敗]
    G -->|Yes| I[return true<br/>キーが離された]
    D --> J[終了]
    F --> J
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-231-01 | フレーム遷移検出 | キーリリースは、前フレームでDown状態かつ現在フレームで!Down状態の場合のみ検出される | 常時 |
| BR-231-02 | オーナーシップ優先 | キーオーナーシップが設定されている場合、オーナー以外からのリリース検出はブロックされる | owner_id指定時 |
| BR-231-03 | 単一フレーム検出 | キーリリースは離された瞬間の1フレームのみtrueを返す | 常時 |

### 計算ロジック

キーリリース判定ロジック：
```
IsKeyReleased = (DownDurationPrev >= 0.0f) && (!Down) && TestKeyOwner(key, owner_id)
```

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

該当なし（メモリ上のキー状態データのみ参照）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーションエラー | 無効なキー（Named Key以外）が指定された場合 | デバッグビルドでアサーションが発生、リリースビルドでは動作継続 |

### リトライ仕様

該当なし（同期的な状態チェック関数のため）

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

該当なし

## パフォーマンス要件

- 処理時間：O(1)の定数時間で完了
- 1フレームあたり複数回呼び出し可能
- メモリアロケーションなし

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

該当なし（UIライブラリ内部の入力状態チェックのみ）

## 備考

- IsKeyReleasedは、IsKeyPressedと対になる関数として設計されている
- マウスボタンに対しては、同等の機能を持つIsMouseReleasedが提供されている
- 内部API版（owner_id引数付き）は、imgui_internal.hで宣言されている

---

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

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

### 推奨読解順序

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

まず、キー入力状態を保持するデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiKeyData構造体（2384-2390行目）でキーの状態データ構造を理解 |
| 1-2 | imgui.h | `imgui.h` | ImGuiKey列挙型でサポートされるキーコードを確認 |

**読解のコツ**: ImGuiKeyData構造体の各メンバの意味を把握することが重要。Down（現在の押下状態）、DownDuration（押下継続時間）、DownDurationPrev（前フレームの押下継続時間）の関係を理解する。

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

処理の起点となるパブリックAPI関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | IsKeyReleased関数の宣言（1060行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | パブリックAPI版の実装（9800-9803行目） |

**主要処理フロー**:
1. **9800-9803行目**: パブリックAPI - owner_idにImGuiKeyOwner_Anyを設定して内部版を呼び出し

#### Step 3: 内部実装を理解する

キーリリース判定の詳細ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui.cpp | `imgui.cpp` | 内部API版IsKeyReleasedの実装（9805-9813行目） |
| 3-2 | imgui.cpp | `imgui.cpp` | GetKeyData関数（9349-9359行目）でキーデータ取得ロジックを確認 |
| 3-3 | imgui.cpp | `imgui.cpp` | TestKeyOwner関数（10544-10559行目）でオーナーシップ検証を確認 |

**主要処理フロー**:
- **9807行目**: GetKeyData(key)でImGuiKeyData構造体のポインタを取得
- **9808-9809行目**: DownDurationPrev < 0.0f または Down == true の場合は早期リターン（false）
- **9810-9811行目**: TestKeyOwner(key, owner_id)でオーナーシップを検証
- **9812行目**: 全条件を満たした場合にtrueを返却

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

```
ImGui::IsKeyReleased(ImGuiKey key)  [Public API - imgui.cpp:9800]
    │
    └─ ImGui::IsKeyReleased(ImGuiKey key, ImGuiID owner_id)  [Internal - imgui.cpp:9805]
           │
           ├─ GetKeyData(key)  [imgui.cpp:9349]
           │      └─ ImGuiIO.KeysData[key - ImGuiKey_NamedKey_BEGIN]
           │
           └─ TestKeyOwner(key, owner_id)  [imgui.cpp:10544]
                  └─ GetKeyOwnerData(&g, key)
```

### データフロー図

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

ImGuiKey key     ───▶ GetKeyData()で
                      ImGuiKeyData取得   ───▶ DownDurationPrev,
                                              Down状態を確認
                                                    │
                                                    ▼
                      TestKeyOwner()で   ◀───────────
                      オーナーシップ検証
                                                    │
                                                    ▼
                                              bool結果を返却 ───▶ 呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | パブリックAPIの宣言、ImGuiKeyData構造体定義 |
| imgui.cpp | `imgui.cpp` | ソース | IsKeyReleasedの実装 |
| imgui_internal.h | `imgui_internal.h` | ヘッダー | 内部API版の宣言、キーオーナーシップ関連定義 |
| imgui_demo.cpp | `imgui_demo.cpp` | ソース | 使用例のデモコード |
