# 帳票設計書 1-パフォーマンスモニターCSV

## 概要

本ドキュメントは、Godotエディタのデバッガーで取得したパフォーマンスモニターデータをCSV形式でエクスポートする帳票の設計書である。

### 本帳票の処理概要

本帳票は、Godotエンジンのエディタデバッガーで収集されたパフォーマンスメトリクスをCSVファイルとして出力する機能を提供する。フレーム時間、プロセス時間、物理時間、メモリ使用量などのシステムパフォーマンス指標と、スクリプトプロファイラーで収集した関数実行時間データを統合して出力する。

**業務上の目的・背景**：ゲーム開発やアプリケーション開発において、パフォーマンスのボトルネックを特定し最適化を行うことは非常に重要である。リアルタイムでの監視だけでなく、データを永続化してオフラインで詳細な分析を行ったり、時系列での比較分析を行う必要がある。本帳票はその基盤データを提供する。

**帳票の利用シーン**：主に以下のシーンで利用される。1) ゲームのリリース前のパフォーマンステスト時、2) 特定シーンやレベルでのフレームレート低下調査時、3) 新機能追加後のパフォーマンス影響評価時、4) 継続的インテグレーション（CI）でのパフォーマンス回帰テスト。

**主要な出力内容**：
1. Performance::MONITOR_MAX種類のシステムメトリクス（FPS、フレーム時間、物理時間、メモリ使用量等）
2. スクリプトプロファイラーから取得した関数ごとの実行時間データ
3. 時系列のフレームごとのデータ推移

**帳票の出力タイミング**：エディタのデバッガパネルにあるパフォーマンスモニタータブで「Export CSV」ボタンをクリックした際に出力される。

**帳票の利用者**：ゲーム開発者、テクニカルアーティスト、QAエンジニア、パフォーマンス最適化担当者

## 帳票種別

データエクスポート / 分析用データ一覧

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| 15 | デバッガ | エディタ内蔵（Debugger Panel） | Monitorsタブの「Export CSV」ボタン |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | CSV |
| 用紙サイズ | N/A（データファイル） |
| 向き | N/A |
| ファイル名 | ユーザー指定（.csvフィルター） |
| 出力方法 | ファイルダイアログでのファイル保存 |
| 文字コード | UTF-8 |

### CSV固有設定

| 項目 | 内容 |
|-----|------|
| 区切り文字 | カンマ（,） |
| 囲み文字 | ダブルクォート（必要時） |
| ヘッダー行 | あり（1行目にカラム名） |

## 帳票レイアウト

### レイアウト概要

CSVファイルは2つのセクションで構成される。前半がシステムパフォーマンスモニターデータ、後半がスクリプトプロファイラーデータである。

```
┌─────────────────────────────────────────────────────────────┐
│              ヘッダー行（モニター名列挙）                      │
├─────────────────────────────────────────────────────────────┤
│              データ行（フレームごとの値）                      │
│              ...（複数行）                                   │
├─────────────────────────────────────────────────────────────┤
│              空行                                           │
├─────────────────────────────────────────────────────────────┤
│              プロファイラーヘッダー行                         │
├─────────────────────────────────────────────────────────────┤
│              プロファイラーデータ行                          │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部（システムモニター）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | time/fps | フレームレート | Performance::TIME_FPS | 実数 |
| 2 | time/process | プロセス時間（秒） | Performance::TIME_PROCESS | 実数 |
| 3 | time/physics_process | 物理処理時間（秒） | Performance::TIME_PHYSICS_PROCESS | 実数 |
| 4 | time/navigation_process | ナビゲーション処理時間 | Performance::TIME_NAVIGATION_PROCESS | 実数 |
| 5 | memory/static | 静的メモリ（バイト） | Performance::MEMORY_STATIC | 実数 |
| 6 | memory/static_max | 静的メモリ最大値 | Performance::MEMORY_STATIC_MAX | 実数 |
| 7 | memory/msg_buf_max | メッセージバッファ最大 | Performance::MEMORY_MESSAGE_BUFFER_MAX | 実数 |
| 8 | object/count | オブジェクト数 | Performance::OBJECT_COUNT | 実数 |
| 9 | object/resource_count | リソース数 | Performance::OBJECT_RESOURCE_COUNT | 実数 |
| 10 | object/node_count | ノード数 | Performance::OBJECT_NODE_COUNT | 実数 |
| 11 | object/orphan_node_count | 孤立ノード数 | Performance::OBJECT_ORPHAN_NODE_COUNT | 実数 |
| 12 | render/... | レンダリング関連メトリクス | Performance::RENDER_* | 実数 |

### 明細部（プロファイラーデータ）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | category/item名 | カテゴリまたは項目のシグネチャ | Metric::category_ptrs/item_ptrs | 文字列 | 可変 |
| 2〜N | 各フレームの値 | 対応フレームでの時間（秒） | Metric::Category::total_time / Item::total | 実数 | 可変 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| デバッガ接続 | リモートデバッガがゲームに接続している必要がある | Yes |
| データ蓄積 | パフォーマンスモニターでデータが収集されている必要がある | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | フレーム順（時系列） | 昇順 |

### 改ページ条件

N/A（CSVファイルのため改ページなし）

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを参照せず、インメモリのパフォーマンスデータを使用する。

| データソース | 用途 | 取得方法 |
|-----------|------|---------|
| Performance singleton | システムモニターデータ | Performance::get_singleton()->get_monitor_name() |
| performance_profiler | 蓄積されたモニターデータ | get_monitor_data() |
| profiler (EditorProfiler) | スクリプトプロファイラーデータ | get_data_as_csv() |

### テーブル別参照項目詳細

#### Performance Singleton

| 参照項目（定数名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| MONITOR_MAX | カラム数の決定 | 常時 | 全モニター種別数 |
| get_monitor_name(i) | ヘッダー行の各カラム名 | 0 <= i < MONITOR_MAX | モニター名取得 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 各メトリクス値 | String::num_real(iterators[i]->get()) | なし | 実数値をそのまま文字列化 |
| プロファイラー時間 | String::num_real(total_time / total) | なし | カテゴリ/項目の合計時間 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[Export CSVボタンクリック] --> B[_export_csv呼び出し]
    B --> C[ファイルダイアログ表示]
    C --> D{ファイル選択}
    D -->|選択| E[_file_selected呼び出し]
    D -->|キャンセル| Z[終了]
    E --> F[ファイルオープン]
    F --> G{オープン成功?}
    G -->|失敗| H[エラー出力]
    G -->|成功| I[ヘッダー行書き込み]
    I --> J[モニターデータ書き込みループ]
    J --> K[空行書き込み]
    K --> L[profiler->get_data_as_csv取得]
    L --> M[プロファイラーデータ書き込み]
    M --> N[ファイルクローズ]
    N --> Z
    H --> Z
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ファイルオープン失敗 | 書き込み権限なし、パス不正など | "Failed to open [path]" | ERR_PRINT出力、処理中断 |
| データなし | モニターデータが空 | なし（空ファイル出力） | 空の状態でも処理継続 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数千フレーム分 |
| 目標出力時間 | 1秒未満 |
| 同時出力数上限 | 1（シングル処理） |

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

- 出力先はユーザーが選択したローカルファイルシステムのみ
- 機密情報は含まれないが、プロジェクト構造がファイル名から推測可能な場合がある
- ファイルアクセス権限はEditorFileDialog::ACCESS_FILESYSTEMで制御

## 備考

- パフォーマンスモニターデータとスクリプトプロファイラーデータは同一CSVファイルに統合される
- データは時系列の逆順（最新から古い順）でイテレートされ、ファイルには古い順に書き込まれる

---

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

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

### 推奨読解順序

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

まず、パフォーマンスモニターのデータ構造とプロファイラーのメトリクス構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | script_editor_debugger.h | `editor/debugger/script_editor_debugger.h` | FileDialogPurpose列挙型（107-110行目）でCSV出力の目的を定義 |
| 1-2 | editor_profiler.h | `editor/debugger/editor_profiler.h` | Metricクラス構造、category_ptrs、item_ptrsの定義を確認 |

**読解のコツ**: C++のポインタマップ（HashMap）の使い方に注目。キーがStringName、値がカテゴリ/アイテムへのポインタとなっている。

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

処理の起点となる関数を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | script_editor_debugger.cpp | `editor/debugger/script_editor_debugger.cpp` | _export_csv()（1390-1395行目）がエクスポートのエントリーポイント |

**主要処理フロー**:
1. **1390行目**: _export_csv()でファイルダイアログを表示設定
2. **1391行目**: FILE_MODE_SAVE_FILEでファイル保存モードに設定
3. **1393行目**: file_dialog_purposeをSAVE_MONITORS_CSVに設定
4. **1394行目**: ファイルダイアログをポップアップ

#### Step 3: ファイル選択後の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | script_editor_debugger.cpp | `editor/debugger/script_editor_debugger.cpp` | _file_selected()（181-259行目）でCSV出力を実行 |

**主要処理フロー**:
- **181-182行目**: file_dialog_purposeでSAVE_MONITORS_CSVを判定
- **184-185行目**: FileAccess::openでファイルを書き込みモードで開く
- **191-198行目**: Performance::MONITOR_MAXをサイズとしてヘッダー行を構築
- **200-220行目**: イテレータを使用してモニターデータを時系列で書き込み
- **223-226行目**: profiler->get_data_as_csv()でプロファイラーデータを取得し追記

#### Step 4: プロファイラーのCSV出力実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | editor_profiler.cpp | `editor/debugger/editor_profiler.cpp` | get_data_as_csv()（600-667行目）でプロファイラーデータをCSV形式に変換 |

**主要処理フロー**:
- **603-605行目**: frame_metricsが空の場合は空のベクターを返す
- **608-620行目**: 全フレームのシグネチャを収集してpossible_signaturesに格納
- **623-632行目**: シグネチャからヘッダー行を生成
- **637-664行目**: last_metricから順にフレームデータを出力

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

```
ScriptEditorDebugger::_export_csv()
    │
    └─ EditorFileDialog::popup_file_dialog()
           │
           └─ ScriptEditorDebugger::_file_selected(path)
                  │
                  ├─ FileAccess::open(path, WRITE)
                  │
                  ├─ Performance::get_singleton()->get_monitor_name(i)
                  │      └─ [モニター名をヘッダーとして出力]
                  │
                  ├─ performance_profiler->get_monitor_data()
                  │      └─ [各モニターのデータリストを取得]
                  │
                  ├─ file->store_csv_line(line)
                  │      └─ [行単位でCSV出力]
                  │
                  └─ EditorProfiler::get_data_as_csv()
                         │
                         └─ [プロファイラーデータをVector<Vector<String>>で返却]
```

### データフロー図

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

Performance Singleton ──────▶ get_monitor_name() ──────────▶ CSVヘッダー行
      │                                                           │
      │                                                           │
performance_profiler ────────▶ get_monitor_data() ─────────▶ モニターデータ行
      │                            │                              │
      │                            │                              │
EditorProfiler ─────────────▶ get_data_as_csv() ───────────▶ プロファイラー
(frame_metrics)                    │                          データ行
                                   │                              │
                                   ▼                              │
                            FileAccess::store_csv_line() ◀────────┘
                                   │
                                   ▼
                              [CSVファイル]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| script_editor_debugger.h | `editor/debugger/script_editor_debugger.h` | ヘッダー | ScriptEditorDebuggerクラス定義、FileDialogPurpose列挙型 |
| script_editor_debugger.cpp | `editor/debugger/script_editor_debugger.cpp` | ソース | CSV出力の主要処理実装 |
| editor_profiler.h | `editor/debugger/editor_profiler.h` | ヘッダー | EditorProfilerクラス定義、Metric構造体 |
| editor_profiler.cpp | `editor/debugger/editor_profiler.cpp` | ソース | get_data_as_csv()の実装 |
| performance.h | `servers/performance.h` | ヘッダー | Performance singleton、MONITOR列挙型定義 |
| file_access.h | `core/io/file_access.h` | ヘッダー | ファイルI/O基盤クラス |
| editor_file_dialog.h | `editor/gui/editor_file_dialog.h` | ヘッダー | ファイル選択ダイアログ |
