# 機能設計書 83-GetID

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるGetID関数の機能設計を定義する。GetIDは、現在のIDスタック全体と指定されたパラメータからハッシュを計算し、一意のIDを取得する機能である。

### 本機能の処理概要

GetID関数は、ImGuiのIDスタックシステムにおいて、現在のIDスタック全体と入力パラメータを組み合わせてハッシュ計算を行い、一意の識別子（ImGuiID）を返す機能を提供する。

**業務上の目的・背景**：ImGuiでは、ウィジェットやストレージへのアクセスに一意のIDが必要である。GetIDを使用することで、現在のIDスコープを考慮した一意のIDを取得でき、ImGuiStorage等への直接アクセスやカスタムウィジェットの実装が可能になる。PushIDでIDスコープを変更した場合、同じ入力パラメータでも異なるIDが生成される点が重要である。

**機能の利用シーン**：
- ImGuiStorageに直接アクセスしてカスタムデータを保存・取得する場合
- カスタムウィジェットの実装でIDを明示的に取得する場合
- ウィジェットのIDを事前に計算して他の処理で使用する場合
- デバッグやロギングでウィジェットIDを確認する場合

**主要な処理内容**：
1. 現在のウィンドウコンテキストを取得
2. window->GetID()を呼び出し、IDスタックトップと入力値からハッシュを計算
3. 計算されたImGuiIDを返す

**関連システム・外部連携**：ImGuiコンテキスト（GImGui）、ImGuiWindow構造体、ハッシュ関数（ImHashStr, ImHashData）

**権限による制御**：なし。すべてのImGuiユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全ウィジェット | 補助機能 | ウィジェットID取得の基盤機能として使用 |

## 機能種別

ユーティリティ機能 / ID計算

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str_id | const char* | Yes（オーバーロード1） | ID計算に使用する文字列 | NULLチェックなし |
| str_id_begin | const char* | Yes（オーバーロード2） | 文字列IDの開始ポインタ | - |
| str_id_end | const char* | Yes（オーバーロード2） | 文字列IDの終了ポインタ | - |
| ptr_id | const void* | Yes（オーバーロード3） | ID計算に使用するポインタ | - |
| int_id | int | Yes（オーバーロード4） | ID計算に使用する整数 | - |

### 入力データソース

呼び出し元コードからの直接入力、および現在のIDスタック状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | ImGuiID | 計算された一意の識別子（unsigned int） |

### 出力先

呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. 現在のウィンドウの取得
   └─ GImGui->CurrentWindowから現在のウィンドウを参照
2. window->GetID()の呼び出し
   └─ ウィンドウのメンバ関数を呼び出し
3. ハッシュ計算
   └─ IDスタックトップをシードとして入力値をハッシュ
4. 結果の返却
   └─ 計算されたImGuiIDを返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[GImGui->CurrentWindowを取得]
    B --> C{入力型の判定}
    C -->|文字列| D[window->GetID で文字列ハッシュ]
    C -->|ポインタ| E[window->GetID でポインタハッシュ]
    C -->|整数| F[window->GetID で整数ハッシュ]
    D --> G[ImGuiID を返す]
    E --> G
    F --> G
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | IDスコープ依存 | 同じ入力でもIDスコープが異なれば異なるIDが生成される | 常時 |
| BR-02 | 決定的計算 | 同じ入力とIDスコープであれば常に同じIDが返される | 常時 |
| BR-03 | ウィンドウ依存 | 現在のウィンドウのIDスタックを使用してIDを計算する | 常時 |

### 計算ロジック

IDはImHashStr/ImHashData関数を使用して計算される。シード値として現在のIDスタックトップ（window->IDStack.back()）が使用され、入力値と組み合わせて一意のIDを生成する。

```
ID = Hash(input, IDStack.back())
```

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

該当なし（メモリ内操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 通常エラーは発生しない | - |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ハッシュ計算は軽量で、1フレーム内で多数回呼び出しても性能に影響しない
- O(1)の時間計算量でID計算を実行

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

特になし。内部メモリ操作のみで外部との通信なし。

## 備考

- GetIDは読み取り専用の操作であり、IDスタックを変更しない
- ImGuiStorageへのアクセス時に使用することで、カスタムデータの永続化が可能
- デバッグ時はImGui::ShowIDStackToolWindow()でIDスタックの状態を確認可能

---

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

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

### 推奨読解順序

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

ImGuiIDとIDスタックの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui.h | `imgui.h` | ImGuiIDの型定義（160行目: `typedef unsigned int ImGuiID`） |
| 1-2 | imgui_internal.h | `imgui_internal.h` | ImGuiWindow構造体のIDStackメンバ（2708行目） |

**読解のコツ**: ImGuiIDは32ビット符号なし整数であり、ハッシュ衝突の可能性は低いが、同一ID衝突時の動作も理解しておくとよい。

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

GetID関数のオーバーロード群を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui.h | `imgui.h` | GetID関数宣言（608-611行目） |
| 2-2 | imgui.cpp | `imgui.cpp` | GetID関数実装（9236-9258行目） |

**主要処理フロー**:
1. **9236-9240行目**: 文字列版GetID - CurrentWindowを取得し、window->GetID(str_id)を呼び出して返す
2. **9242-9246行目**: 文字列範囲版GetID - 同様の処理で文字列範囲のハッシュを計算
3. **9248-9252行目**: ポインタ版GetID - ポインタ値のハッシュを計算
4. **9254-9258行目**: 整数版GetID - 整数値のハッシュを計算

#### Step 3: ウィンドウのGetIDメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_internal.h | `imgui_internal.h` | ImGuiWindow::GetID宣言（2756-2758行目） |
| 3-2 | imgui.cpp | `imgui.cpp` | ImGuiWindow::GetID実装 |

**主要処理フロー**:
- **ImGuiWindow::GetID**: IDStackの最後の要素をシードとしてハッシュ計算を実行

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

```
ImGui::GetID(const char* str_id)
    │
    ├─ GImGui->CurrentWindow（ウィンドウ参照）
    │
    └─ window->GetID(str_id)
           │
           └─ ImHashStr(str_id, 0, IDStack.back())
```

### データフロー図

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

str_id/ptr_id/int_id ───▶ window->GetID() ───▶ ImGuiID
                               │
                               ├── IDStack.back()（シード値）
                               │
                               └── ImHashStr/ImHashData
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui.h | `imgui.h` | ヘッダー | GetID関数の宣言（608-611行目）、ImGuiID型定義 |
| imgui.cpp | `imgui.cpp` | ソース | GetID関数の実装（9236-9258行目） |
| imgui_internal.h | `imgui_internal.h` | 内部ヘッダー | ImGuiWindow構造体、IDStack定義、GetIDメソッド宣言 |
