# 画面設計書 17-Script Editor

## 概要

本ドキュメントは、three.js エディタにおけるスクリプトエディタ（Script Editor）の画面設計書である。このエディタは、オブジェクトに紐付くJavaScriptスクリプトやシェーダー（GLSL）の編集機能を提供する、CodeMirrorベースのコードエディタである。

### 本画面の処理概要

**業務上の目的・背景**：3Dシーンにインタラクティブな動作を付与するには、JavaScriptによるスクリプティングが不可欠である。また、高度なビジュアル表現にはカスタムシェーダー（Vertex Shader / Fragment Shader）の編集が必要となる場合がある。Script Editorは、これらのコードをエディタ内で直接編集し、リアルタイムで結果を確認できる統合開発環境を提供する。

**画面へのアクセス方法**：以下のいずれかの方法でScript Editorが表示される。
- Sidebar - Scriptパネルでスクリプトを選択・編集時
- シェーダーマテリアル（ShaderMaterial/RawShaderMaterial）のVertex Shader / Fragment Shader / Program Info編集時

**主要な操作・処理内容**：
1. **JavaScript編集**：オブジェクトに紐付くイベントスクリプト（init, start, update等）の編集
2. **GLSL編集**：Vertex Shader / Fragment Shaderの編集
3. **JSON編集**：シェーダーのdefines, uniforms, attributesの編集（Program Info）
4. **リアルタイム検証**：構文エラーのハイライト表示（esprima/jsonlint/GLSL diagnostics）
5. **オートコンプリート**：Tern.jsによるThree.js APIの補完

**画面遷移**：Script Editorは独立したパネルとして表示/非表示が切り替わる。閉じるボタン（X）で非表示にできる。

**権限による表示制御**：特別な権限制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | ShaderMaterial | 主機能 | カスタムシェーダーの編集 |
| 64 | RawShaderMaterial | 主機能 | Rawシェーダーの編集 |
| 5 | EventDispatcher | 補助機能 | スクリプト変更イベントの発行 |

## 画面種別

コードエディタパネル

## URL/ルーティング

エディタメイン画面の一部として `editor/index.html` に含まれる。独立したルーティングは持たない。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| currentObject | 入力 | Object3D | 編集対象のオブジェクト |
| currentScript | 入力 | Object/String | 編集対象のスクリプトまたはシェーダータイプ |
| source | 入出力 | String | スクリプト/シェーダーのソースコード |

## 表示項目

| 項目 | 表示内容 | 説明 |
|------|---------|------|
| ヘッダー | オブジェクト名 / スクリプト名 | 編集中のコンテキストを表示 |
| 閉じるボタン | X アイコン（SVG） | クリックでエディタを閉じる |
| コードエリア | CodeMirror | シンタックスハイライト付きコードエディタ |
| エラー表示 | 行ハイライト + メッセージ | 構文エラーの位置と内容 |

## イベント仕様

### 1-editScript（スクリプト編集開始）

- **トリガー**：`signals.editScript` が発行された時
- **処理内容**：
  1. 編集モードを判定（javascript / glsl / json）
  2. ソースコードを取得
  3. タイトルを設定（オブジェクト名 / スクリプト名）
  4. CodeMirrorにソースコードを設定
  5. パネルを表示
- **画面更新**：Script Editorパネルが表示され、コードが読み込まれる

### 2-コード変更時（on 'change'）

- **トリガー**：CodeMirrorでコードが変更された時
- **処理内容**：
  1. 300msのデバウンス処理
  2. validate()関数でコードを検証
  3. 検証成功時、対応するCommandを実行
     - JavaScript: `SetScriptValueCommand`
     - GLSL: マテリアルに直接設定 + `materialChanged`シグナル
     - JSON: `SetMaterialValueCommand`（defines, uniforms, attributes）
- **画面更新**：エラーがあれば行ハイライトとウィジェット表示

### 3-validate（コード検証）

- **トリガー**：コード変更後のデバウンス完了時
- **処理内容**：
  - **JavaScript**: esprima.parse()で構文解析
  - **JSON**: jsonlint.parse()で構文解析
  - **GLSL**: renderer.info.programsからdiagnosticsを取得
- **結果**：エラー行にerrorLineクラスを適用、エラーメッセージをLineWidgetで表示

### 4-close（エディタを閉じる）

- **トリガー**：閉じるボタンクリック
- **処理内容**：
  1. `container.setDisplay('none')` でパネルを非表示
- **画面更新**：Script Editorパネルが非表示になる

### 5-editorCleared（エディタクリア時）

- **トリガー**：`signals.editorCleared` が発行された時
- **処理内容**：
  1. `container.setDisplay('none')` でパネルを非表示
- **目的**：新規プロジェクト時にエディタを閉じる

### 6-scriptRemoved（スクリプト削除時）

- **トリガー**：`signals.scriptRemoved` が発行された時
- **処理内容**：
  1. 現在編集中のスクリプトが削除された場合、パネルを非表示
- **目的**：編集対象が存在しなくなった場合の対応

## データベース更新仕様

本画面はブラウザ上で動作する3Dエディタであり、データベースへの直接的な更新は行わない。スクリプト変更はCommandパターンで履歴管理される。

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|---------------|---------------|---------|
| エラー（行内） | 構文エラーメッセージ | JavaScript/JSON/GLSLの構文エラー時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| 構文エラー | 該当行にerrorLineクラスを適用、エラーメッセージをウィジェット表示 |
| 未知のスクリプトタイプ | throw new Error('editScript: Unknown script') |

## 備考

- CodeMirrorの設定：
  - テーマ: monokai
  - 行番号表示: 有効
  - 括弧マッチ: 有効
  - タブサイズ: 4
  - インデント: タブ
- Tern.jsによるオートコンプリート対応（Ctrl+Space）
- Ctrl+I: 型情報表示
- Ctrl+O: ドキュメント表示
- Alt+.: 定義にジャンプ
- Alt+,: 戻る
- Ctrl+Q: リネーム
- Ctrl+.: 名前選択

---

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

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

### 推奨読解順序

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

スクリプトとシェーダーの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Sidebar.Script.js | `editor/js/Sidebar.Script.js` | スクリプトオブジェクトの構造 |

**読解のコツ**: スクリプトはname, sourceプロパティを持つオブジェクト。シェーダーは文字列タイプ('vertexShader', 'fragmentShader', 'programInfo')で識別。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Script.js | `editor/js/Script.js` | コードエディタの主要実装 |

**主要処理フロー**:
1. **6-47行目**: UIPanel構築、ヘッダー、閉じるボタン
2. **64-75行目**: CodeMirrorの初期化と設定
3. **76-129行目**: 変更時のハンドラ（デバウンス + validate + Command実行）
4. **144-289行目**: validate()関数（JavaScript/JSON/GLSL検証）
5. **293-334行目**: Tern.jsのextraKeys設定
6. **398-457行目**: editScriptシグナルハンドラ

#### Step 3: コマンドクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SetScriptValueCommand.js | `editor/js/commands/SetScriptValueCommand.js` | スクリプト値更新コマンド |
| 3-2 | SetMaterialValueCommand.js | `editor/js/commands/SetMaterialValueCommand.js` | マテリアル値更新コマンド |

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

```
Script (Script.js)
    │
    ├─ signals.editScript.add(callback)
    │      ├─ モード判定 (javascript / glsl / json)
    │      ├─ setTitle()
    │      ├─ codemirror.setValue()
    │      └─ container.setDisplay('')
    │
    ├─ codemirror.on('change', callback)
    │      └─ setTimeout(300ms)
    │             ├─ validate()
    │             │      ├─ JavaScript: esprima.parse()
    │             │      ├─ JSON: jsonlint.parse()
    │             │      └─ GLSL: renderer.info.programs
    │             └─ 成功時
    │                    ├─ JavaScript: SetScriptValueCommand
    │                    ├─ GLSL: material[shader] = value
    │                    └─ JSON: SetMaterialValueCommand
    │
    └─ close.onClick()
           └─ container.setDisplay('none')
```

### データフロー図

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

signals.editScript ─────▶ Script.js ───────────────▶ CodeMirror表示
(object, script)              │
                              │
コード入力 ──────────────────▶ validate() ──────────────▶ エラー表示
                              │
                              └─ SetScriptValueCommand/
                                 SetMaterialValueCommand
                                      │
                                      ▼
                               オブジェクト/マテリアル更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Script.js | `editor/js/Script.js` | ソース | Script Editorの主要実装 |
| SetScriptValueCommand.js | `editor/js/commands/SetScriptValueCommand.js` | ソース | スクリプト値更新コマンド |
| SetMaterialValueCommand.js | `editor/js/commands/SetMaterialValueCommand.js` | ソース | マテリアル値更新コマンド |
| ui.js | `editor/js/libs/ui.js` | ソース | UIコンポーネント |
| codemirror.js | 外部ライブラリ | ライブラリ | コードエディタ |
| esprima.js | 外部ライブラリ | ライブラリ | JavaScript構文解析 |
| jsonlint.js | 外部ライブラリ | ライブラリ | JSON構文解析 |
| tern.js | 外部ライブラリ | ライブラリ | JavaScript補完 |
