# 機能設計書 99-LoadingManager

## 概要

本ドキュメントは、Three.jsライブラリにおける複数リソースの読み込み進捗管理機能（LoadingManager）の設計仕様を記述したものである。

### 本機能の処理概要

LoadingManagerは、複数のローダーが読み込むリソースの進捗を一元管理する機能を提供する。読み込み開始、進捗、完了、エラーのコールバックを管理し、URL変換機能やローダーハンドラーの登録機能も備える。

**業務上の目的・背景**：3Dアプリケーションでは多数のリソース（テクスチャ、モデル、音声等）を非同期で読み込む必要がある。ローディング画面の表示、進捗バーの更新、すべてのリソース読み込み完了の検知など、一元的な読み込み管理が不可欠である。LoadingManagerはこれらの管理機能を提供する。

**機能の利用シーン**：
- ローディング画面の進捗表示
- 複数リソースの読み込み完了検知
- テクスチャとモデルで別々の進捗バーを表示
- ドラッグ&ドロップやData URIからのリソース読み込み
- カスタムローダーの登録（TGA、HDR等）
- 読み込みリクエストの中断

**主要な処理内容**：
1. onStart、onProgress、onLoad、onErrorコールバックの管理
2. itemStart()、itemEnd()、itemError()による進捗追跡
3. resolveURL()によるURL変換
4. setURLModifier()によるカスタムURL変換の設定
5. addHandler()/removeHandler()/getHandler()によるローダーハンドラー管理
6. abort()による読み込み中断

**関連システム・外部連携**：すべてのLoaderクラス、DefaultLoadingManager（グローバルインスタンス）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | Menubar - File | 主機能 | ファイル読み込み進捗管理 |
| 19 | GLTF Import Dialog | 補助機能 | インポート進捗管理 |

## 機能種別

管理機能 / 進捗追跡

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| onLoad | Function | No | 全アイテム読み込み完了時のコールバック | 関数 |
| onProgress | Function | No | 各アイテム読み込み完了時のコールバック | 関数 |
| onError | Function | No | エラー発生時のコールバック | 関数 |

### 入力データソース

各ローダーからのitemStart/itemEnd/itemError呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| onStart | Function\|undefined | 読み込み開始時コールバック |
| onLoad | Function\|undefined | 全完了時コールバック |
| onProgress | Function\|undefined | 進捗コールバック |
| onError | Function\|undefined | エラーコールバック |
| abortController | AbortController | 中断制御用 |

### 出力先

コールバック関数を通じてアプリケーションに通知

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ コールバック関数の設定
   └─ 内部状態の初期化（isLoading, itemsLoaded, itemsTotal）
2. ローダーからitemStart呼び出し
   └─ itemsTotal++
   └─ 初回の場合onStartコールバック実行
3. ローダーからitemEnd呼び出し
   └─ itemsLoaded++
   └─ onProgressコールバック実行
   └─ 全完了の場合onLoadコールバック実行
4. エラー時itemError呼び出し
   └─ onErrorコールバック実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始: new LoadingManager] --> B[コールバック設定]
    B --> C[内部状態初期化]
    C --> D[待機状態]

    E[itemStart呼び出し] --> F[itemsTotal++]
    F --> G{初回読み込み?}
    G -->|Yes| H[onStart実行]
    G -->|No| I[継続]
    H --> I

    J[itemEnd呼び出し] --> K[itemsLoaded++]
    K --> L[onProgress実行]
    L --> M{全完了?}
    M -->|Yes| N[onLoad実行]
    M -->|No| O[継続]

    P[itemError呼び出し] --> Q[onError実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-99-01 | 初回検知 | isLoading = falseからtrueへの変化でonStart実行 | 常時 |
| BR-99-02 | 完了検知 | itemsLoaded === itemsTotalでonLoad実行 | 常時 |
| BR-99-03 | 進捗通知 | itemEnd時に毎回onProgress実行 | 常時 |
| BR-99-04 | URL変換 | setURLModifierで登録した関数でURL変換 | URL解決時 |
| BR-99-05 | ハンドラー検索 | 正規表現マッチでローダーを選択 | getHandler時 |

### 計算ロジック

進捗率: `progress = itemsLoaded / itemsTotal`

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 読み込みエラー | ローダーでエラー発生 | onErrorで処理 |
| - | 中断 | abort()呼び出し | AbortSignalで検知 |

### リトライ仕様

LoadingManager自体はリトライ機能を持たない。必要に応じてアプリケーション側で実装。

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

該当なし

## パフォーマンス要件

- ハンドラー検索はO(n)（登録数に比例）
- 大量のリソース読み込み時はonProgressの実行頻度に注意

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

- setURLModifierで外部URLへのリダイレクトが可能なため、信頼できる変換関数を使用すること

## 備考

- DefaultLoadingManagerはグローバルで共有されるインスタンス
- 別々のローディングバーを表示したい場合は複数のLoadingManagerを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LoadingManager.js | `src/loaders/LoadingManager.js` | クロージャ変数とメソッドの関係を理解 |

**読解のコツ**: LoadingManagerはクロージャを多用しており、内部状態（isLoading, itemsLoaded, itemsTotal, handlers）はコンストラクタ内のローカル変数として定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LoadingManager.js | `src/loaders/LoadingManager.js` | コンストラクタ全体を通して確認 |

**主要処理フロー**:
1. **18行目**: クラス定義開始 `class LoadingManager`
2. **27行目**: コンストラクタ - onLoad, onProgress, onError引数
3. **31-35行目**: クロージャ変数定義 - isLoading, itemsLoaded, itemsTotal, urlModifier, handlers
4. **46行目**: onStart = undefined（コンストラクタ外で設定）
5. **54行目**: onLoad = onLoad引数
6. **62行目**: onProgress = onProgress引数
7. **70行目**: onError = onError引数
8. **78行目**: _abortController = null
9. **86-102行目**: itemStart()メソッド - 読み込み開始通知
10. **110-132行目**: itemEnd()メソッド - 読み込み完了通知
11. **140-148行目**: itemError()メソッド - エラー通知
12. **157-167行目**: resolveURL()メソッド - URL解決
13. **203-209行目**: setURLModifier()メソッド - URL変換関数設定
14. **225-231行目**: addHandler()メソッド - ローダーハンドラー登録
15. **239-251行目**: removeHandler()メソッド - ハンドラー削除
16. **259-278行目**: getHandler()メソッド - ハンドラー取得
17. **287-295行目**: abort()メソッド - 読み込み中断
18. **307-317行目**: abortControllerゲッター - 遅延初期化
19. **327行目**: DefaultLoadingManager定義

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

```
LoadingManager
    │
    ├─ itemStart(url)
    │      └─ onStart(url, itemsLoaded, itemsTotal)
    │
    ├─ itemEnd(url)
    │      ├─ onProgress(url, itemsLoaded, itemsTotal)
    │      └─ onLoad() [全完了時]
    │
    ├─ itemError(url)
    │      └─ onError(url)
    │
    ├─ resolveURL(url)
    │      └─ urlModifier(url) [設定時]
    │
    ├─ addHandler(regex, loader)
    │
    ├─ getHandler(file)
    │      └─ regex.test(file)
    │
    └─ abort()
           └─ abortController.abort()

DefaultLoadingManager (グローバルインスタンス)
    │
    └─ すべてのLoader (デフォルト使用)
```

### データフロー図

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

Loader.load()        ───▶  itemStart()              ───▶  onStart callback
                           │
                           └─ itemsTotal++

読み込み完了          ───▶  itemEnd()                ───▶  onProgress callback
                           │                              │
                           └─ itemsLoaded++               └─ onLoad callback [全完了時]

読み込みエラー        ───▶  itemError()              ───▶  onError callback

URL解決要求          ───▶  resolveURL()             ───▶  変換後URL
                           │
                           └─ urlModifier() [設定時]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LoadingManager.js | `src/loaders/LoadingManager.js` | ソース | 読み込み管理クラス |
| Loader.js | `src/loaders/Loader.js` | ソース | ローダー基底クラス |
| FileLoader.js | `src/loaders/FileLoader.js` | ソース | LoadingManagerを使用するローダー例 |
| ImageLoader.js | `src/loaders/ImageLoader.js` | ソース | LoadingManagerを使用するローダー例 |
