# 機能設計書 44-GDExtension

## 概要

本ドキュメントは、Godot Engineにおけるネイティブ拡張機能「GDExtension」について、設計仕様を記載する。

### 本機能の処理概要

GDExtensionは、C/C++などのネイティブ言語で記述されたダイナミックリンクライブラリ（DLL/SO/dylib）をGodot Engineに動的にロードし、Godotの機能を拡張するためのシステムである。GDNative（Godot 3.x）の後継として設計され、より安定したABIとホットリロード機能を提供する。

**業務上の目的・背景**：高性能な処理（物理シミュレーション、AIアルゴリズム、画像処理等）や既存のC/C++ライブラリをGodotに統合する必要がある場合に使用する。エンジン本体を再コンパイルすることなく、ネイティブコードの機能を追加できる。

**機能の利用シーン**：
- パフォーマンス重視の処理（物理演算、AI、信号処理）
- 既存C/C++ライブラリの統合（OpenCV、TensorFlow等）
- プラットフォーム固有機能の実装
- クローズドソースのプラグイン配布
- サードパーティプラグインのエコシステム

**主要な処理内容**：
1. ネイティブライブラリ（.gdextension）の読み込み
2. 初期化関数（gdextension_init）の呼び出し
3. クラス・メソッド・プロパティ・シグナルの登録
4. Godotオブジェクトとの相互運用
5. ホットリロードによる開発効率化
6. 終了時のクリーンアップ

**関連システム・外部連携**：ClassDB、ObjectDB、リソースローダー、エディタプラグインシステムと連携する。

**権限による制御**：初期化レベル（CORE/SERVERS/SCENE/EDITOR）により、機能が利用可能になるタイミングを制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | GDExtensionはバックエンド機能のため、直接的な画面関連なし |

## 機能種別

プラグインシステム / ネイティブ拡張

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| extension_path | String | Yes | .gdextensionファイルパス | 有効なパス |
| library_path | String | Yes | ネイティブライブラリパス | プラットフォーム別 |
| entry_symbol | String | No | エントリーポイント関数名 | 有効なシンボル名 |
| compatibility_minimum | String | No | 最小互換バージョン | x.y.z形式 |

### 入力データソース

- .gdextension設定ファイル（INI形式）
- ネイティブライブラリ（.dll/.so/.dylib）
- godot-cpp等のバインディングライブラリ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GDExtension | Resource | 拡張機能リソース |
| LoadStatus | enum | ロード結果（OK/FAILED/ALREADY_LOADED等） |
| registered_classes | List<StringName> | 登録されたクラス一覧 |

### 出力先

- ClassDBへのクラス登録
- エディタへのカスタムアイコン登録

## 処理フロー

### 処理シーケンス

```
1. 設定ファイル読み込み
   └─ .gdextensionファイルのパース
   └─ プラットフォーム別ライブラリパス解決

2. ライブラリロード
   └─ GDExtension::open_library()
   └─ dlopen/LoadLibrary呼び出し
   └─ エントリーポイント取得

3. 初期化
   └─ gdextension_init()呼び出し
   └─ GDExtensionInitialization構造体設定
   └─ 最小初期化レベル設定

4. クラス登録
   └─ _register_extension_class5()
   └─ メソッド/プロパティ/シグナル登録
   └─ ClassDBへの追加

5. 利用開始
   └─ initialize_library()各レベルで呼び出し
   └─ オブジェクト生成可能

6. アンロード
   └─ deinitialize_library()
   └─ close_library()
   └─ リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[.gdextensionファイル] --> B[ResourceLoader]
    B --> C[GDExtensionResourceLoader]
    C --> D[load_gdextension_resource]
    D --> E[ConfigFile読み込み]
    E --> F{プラットフォーム判定}
    F --> G[ライブラリパス解決]
    G --> H[GDExtension::open_library]
    H --> I[dlopen/LoadLibrary]
    I --> J{ロード成功?}
    J -->|No| K[LOAD_STATUS_FAILED]
    J -->|Yes| L[エントリーポイント取得]
    L --> M[gdextension_init呼び出し]
    M --> N[InitializationLevel設定]
    N --> O[GDExtensionManager登録]
    O --> P[initialize_extensions]
    P --> Q[CORE→SERVERS→SCENE→EDITOR]
    Q --> R[クラス/メソッド/プロパティ登録]
    R --> S[使用可能]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | 初期化レベル順序 | CORE→SERVERS→SCENE→EDITORの順で初期化 | 拡張機能初期化時 |
| BR-44-02 | ABI互換性 | compatibility_minimumでバージョン互換性を宣言 | ライブラリロード時 |
| BR-44-03 | ホットリロード | reloadableフラグでリロード可否を制御 | 開発時 |
| BR-44-04 | プラットフォーム別ライブラリ | [libraries]セクションでOS別パスを指定 | ビルド構成時 |

### 計算ロジック

- 初期化レベル: CORE(0) < SERVERS(1) < SCENE(2) < EDITOR(3)
- バージョン比較: major.minor.patch形式で互換性判定

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LOAD_STATUS_FAILED | ロードエラー | ライブラリファイル不正/不在 | パス・ビルド確認 |
| LOAD_STATUS_ALREADY_LOADED | 重複ロード | 同一拡張機能の再ロード | アンロード後に再ロード |
| LOAD_STATUS_NOT_LOADED | 未ロード | 未登録拡張機能のアンロード試行 | ロード状態確認 |
| LOAD_STATUS_NEEDS_RESTART | 再起動必要 | ホットリロード不可の変更 | エディタ再起動 |

### リトライ仕様

reload_extension()でホットリロード試行可能（reloadable=trueの場合）

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

該当なし

## パフォーマンス要件

- ネイティブコード実行: GDScript比で数倍〜数十倍高速
- 初期化時間: ライブラリサイズに依存
- メモリ使用: ネイティブヒープで管理

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

- ネイティブコードはサンドボックス外で実行される
- 信頼できないソースのGDExtensionは危険
- コード署名による検証を推奨

## 備考

- godot-cpp（C++バインディング）が公式推奨
- Rust、Go、D言語等のバインディングもコミュニティで提供
- .gdextension形式はGodot 4.0以降

---

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

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

### 推奨読解順序

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

まず、GDExtensionの核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | gdextension.h | `core/extension/gdextension.h` | GDExtensionクラス、Extension構造体 |
| 1-2 | gdextension_manager.h | `core/extension/gdextension_manager.h` | GDExtensionManager、LoadStatus |
| 1-3 | gdextension_interface.h | `core/extension/gdextension_interface.h` | C API定義 |

**読解のコツ**: GDExtensionはResourceを継承し、拡張機能をリソースとして管理する。Extension構造体がクラスごとの情報を保持。

#### Step 2: ライブラリロードを理解する

ネイティブライブラリのロードプロセスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gdextension.h | `core/extension/gdextension.h` | open_library(), close_library() |
| 2-2 | gdextension_loader.h | `core/extension/gdextension_loader.h` | GDExtensionLoaderクラス |

**主要処理フロー**:
- **139-141行目**: open_library(), close_library(), is_library_open()
- **143-148行目**: InitializationLevel enum（CORE/SERVERS/SCENE/EDITOR）
- **171-173行目**: initialize_library(), deinitialize_library()

#### Step 3: クラス登録を理解する

拡張クラスのClassDBへの登録処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | gdextension.h | `core/extension/gdextension.h` | _register_extension_class*メソッド群 |
| 3-2 | gdextension.cpp | `core/extension/gdextension.cpp` | 登録処理の実装 |

**主要処理フロー**:
- **81-86行目**: _register_extension_class〜_register_extension_class5（バージョン別）
- **88-96行目**: メソッド、プロパティ、シグナル登録
- **50-64行目**: Extension構造体（ObjectGDExtension, methods, instances）

#### Step 4: マネージャーを理解する

拡張機能全体の管理を担当するGDExtensionManager。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | gdextension_manager.h | `core/extension/gdextension_manager.h` | ロード/アンロードAPI |
| 4-2 | gdextension_manager.cpp | `core/extension/gdextension_manager.cpp` | 実装詳細 |

**主要処理フロー**:
- **53-59行目**: LoadStatus enum
- **71-78行目**: load_extension(), reload_extension(), unload_extension()
- **83-84行目**: initialize_extensions(), deinitialize_extensions()
- **93-99行目**: load_extensions(), reload_extensions(), startup(), shutdown(), frame()

#### Step 5: ホットリロードを理解する

開発時のホットリロード機能。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | gdextension.h | `core/extension/gdextension.h` | TOOLS_ENABLEDブロック |
| 5-2 | gdextension_manager.cpp | `core/extension/gdextension_manager.cpp` | reload_extension() |

**主要処理フロー**:
- **48行目**: reloadableフラグ
- **104-118行目**: prepare_reload(), finish_reload(), clear_instance_bindings()
- **160-166行目**: has_library_changed(), track/untrack_instance_binding()

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

```
GDExtensionManager::load_extension()
    │
    ├─ GDExtensionResourceLoader::load()
    │      └─ load_gdextension_resource()
    │             ├─ ConfigFile読み込み
    │             └─ GDExtension::open_library()
    │                    ├─ GDExtensionLoader::open_library()
    │                    │      └─ dlopen/LoadLibrary
    │                    └─ gdextension_init()呼び出し
    │
    └─ _load_extension_internal()
           └─ gdextension_map登録

GDExtensionManager::initialize_extensions(level)
    │
    └─ GDExtension::initialize_library(level)
           └─ initialization.initialize(userdata, level)

_register_extension_class5()
    │
    ├─ Extension構造体作成
    │      └─ ObjectGDExtension設定
    │
    ├─ ClassDB::register_extension_class()
    │
    └─ _register_extension_class_method()
    └─ _register_extension_class_property()
    └─ _register_extension_class_signal()

GDExtensionManager::reload_extension()
    │
    ├─ GDExtension::prepare_reload()
    │      └─ インスタンス状態保存
    │
    ├─ close_library() → open_library()
    │
    └─ GDExtension::finish_reload()
           └─ インスタンス状態復元
```

### データフロー図

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

.gdextension設定 ────▶ ConfigFileパース ────▶ ライブラリパス
                              │
                              ▼
ネイティブDLL/SO ────▶ dlopen/LoadLibrary ────▶ 関数ポインタ
                              │
                              ▼
gdextension_init ────▶ 初期化コールバック ────▶ GDExtensionInitialization
                              │
                              ▼
クラス定義 ────────▶ _register_extension_class ────▶ ClassDB登録
                              │
                              ▼
メソッド/プロパティ ────▶ ObjectGDExtension ────▶ インスタンス利用可能
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| gdextension.h | `core/extension/gdextension.h` | ヘッダー | GDExtensionクラス定義 |
| gdextension.cpp | `core/extension/gdextension.cpp` | ソース | GDExtension実装 |
| gdextension_manager.h | `core/extension/gdextension_manager.h` | ヘッダー | マネージャー定義 |
| gdextension_manager.cpp | `core/extension/gdextension_manager.cpp` | ソース | マネージャー実装 |
| gdextension_interface.h | `core/extension/gdextension_interface.h` | ヘッダー | C API定義 |
| gdextension_interface.gen.h | `core/extension/gdextension_interface.gen.h` | 生成ヘッダー | 自動生成C API |
| gdextension_loader.h | `core/extension/gdextension_loader.h` | ヘッダー | ローダー定義 |
| gdextension_loader.cpp | `core/extension/gdextension_loader.cpp` | ソース | ローダー実装 |
| gdextension_compat_hashes.h | `core/extension/gdextension_compat_hashes.h` | ヘッダー | 互換性ハッシュ |
| gdextension_library_loader.h | `core/extension/gdextension_library_loader.h` | ヘッダー | ライブラリローダー |
| gdextension_library_loader.cpp | `core/extension/gdextension_library_loader.cpp` | ソース | ライブラリローダー実装 |
