# Scene - 씬 관리 서브시스템

**"YAML에서 World로"**를 담당하는 씬 로딩 및 전환 계층입니다.

## 📦 모듈 구성

### `manager.rs`
- **`SceneManager`**: 씬의 최상위 관리자
- YAML 파일 기반 씬 로딩
- 엔티티 생명주기 관리 (생성/삭제)
- Engine이 소유하는 유일 인스턴스

```rust
let mut scene_manager = SceneManager::new("templates/");
scene_manager.load_scene("main_menu", &mut world)?;
```

### `manifest/` - YAML 파싱
YAML 파일을 Rust 구조체로 변환

- **`loader.rs`**: 파일 I/O 및 디시리얼라이즈
- **`structure.rs`**: `SceneManifest`, `EntityInstance` 정의
- **`yaml_support.rs`**: 타입 안전한 키 관리

```rust
let manifest = load_scene_manifest("world/scenes/main_menu.yaml")?;
```

### `solver.rs` - 템플릿 해석
템플릿 상속 및 컴포넌트 병합

- 템플릿 캐싱 (성능 최적화)
- 컴포넌트 오버라이드 처리
- 최종 해석된 씬 생성

```rust
let resolved = solver.resolve_scene(&manifest)?;
```

### `factory.rs` - 컴포넌트 생성
YAML 데이터를 실제 Component로 변환

- `ComponentFactory` trait 정의
- `ComponentRegistry` (팩토리 관리)
- Transform, Sprite, Text 팩토리 구현

```rust
let component = registry.create("Transform", &yaml_data)?;
```

## 🎯 설계 철학

### 유일 인스턴스 (Singleton-like)
`SceneManager`는 Engine이 단 하나만 소유하며, 모든 씬 전환을 중앙화합니다.

```
Engine
└── SceneManager (1개)
    ├── manifest_solver: ManifestSolver (템플릿 캐시)
    ├── component_registry: ComponentRegistry (팩토리들)
    ├── current_scene: Option<String>
    └── scene_entities: HashMap<String, Vec<EntityId>>
```

### 선언적 씬 정의
코드 대신 YAML로 씬을 정의하여 빠른 프로토타이핑이 가능합니다.

```yaml
# world/scenes/main_menu.yaml
entities:
  title:
    template: "ui/text_label"
    Transform:
      position: [640, 180]
    Text:
      content: "MAIN MENU"
```

### 템플릿 재사용
공통 엔티티 구조를 템플릿으로 정의하고 재사용합니다.

```yaml
# world/entities/ui/text_label.yaml (템플릿)
components:
  Transform: { position: [0, 0], scale: [1, 1] }
  Text: { content: "", font_size: 24, color: [1, 1, 1, 1] }
```

## 📊 씬 로딩 흐름

### 전체 파이프라인
```
SceneManager::load_scene("main_menu", &world)
├── 1. 기존 씬 언로드
│   └── scene_entities[old] 모두 world.destroy_entity()
│
├── 2. YAML 로드
│   └── manifest::load_scene_manifest("world/scenes/main_menu.yaml")
│
├── 3. 템플릿 해석
│   ├── solver.resolve_scene(&manifest)
│   ├── 템플릿 로드 및 캐싱
│   └── 컴포넌트 병합 (템플릿 + 오버라이드)
│
├── 4. 엔티티 생성
│   ├── world.create_entity()
│   ├── factory.create("Transform", yaml)
│   ├── factory.create("Sprite", yaml)
│   └── entity.add_component_boxed(component)
│
└── 5. 추적 정보 저장
    └── scene_entities["main_menu"] = [entity_ids...]
```

## 🔗 관련 계층

- **`runtime/`**: `Engine`이 `SceneManager` 소유 (선택적)
- **`core/`**: `Entity`, `Component` trait 사용
- **`entity/components/`**: Transform, Sprite, Text 등 구현

## 🚀 사용 예시

### SceneManager 생성
```rust
let mut scene_manager = SceneManager::new("templates/shooter-tutorial");
```

### 씬 로드
```rust
// YAML 파일에서 씬 로드 (자동으로 World에 엔티티 생성)
scene_manager.load_scene("main_menu", &mut world)?;

// 렌더링 (생성된 엔티티들 자동 처리)
render_system.render(&world)?;
```

### 씬 전환
```rust
// 기존 씬 정리 + 새 씬 로드
scene_manager.transition_to_scene("game_level1", &mut world)?;
```

### 현재 씬 확인
```rust
if let Some(current) = scene_manager.current_scene() {
    println!("Current scene: {}", current);
}
```

### 커스텀 컴포넌트 추가
```rust
// 1. ComponentFactory 구현
struct VelocityFactory;
impl ComponentFactory for VelocityFactory {
    fn create_component(&self, yaml: &Value) -> Result<Box<dyn Component>, FactoryError> {
        let x = yaml["x"].as_f64().unwrap_or(0.0) as f32;
        let y = yaml["y"].as_f64().unwrap_or(0.0) as f32;
        Ok(Box::new(Velocity { x, y }))
    }
}

// 2. 레지스트리에 등록
scene_manager.component_registry.register("Velocity", VelocityFactory);

// 3. YAML에서 사용
// entities:
//   player:
//     Velocity: { x: 100, y: 0 }
```

## 💡 YAML 파일 구조

### 씬 파일 (world/scenes/*.yaml)
```yaml
entities:
  entity_name:
    template: "optional/template/path"  # 템플릿 상속
    ComponentName:                      # 직접 정의 또는 오버라이드
      property: value
```

### 템플릿 파일 (world/entities/**/*.yaml)
```yaml
components:
  ComponentName:
    property: default_value
```

### 실제 예시
```yaml
# world/scenes/main_menu.yaml
entities:
  background:
    template: "environment/static_background"
    Sprite:
      texture: "backgrounds/menu.png"
  
  title:
    template: "ui/text_label"
    Transform:
      position: [640, 100]
    Text:
      content: "SHOOTER GAME"
      font_size: 48
```

## ⚡ 성능 최적화

### 템플릿 캐싱
```rust
// 첫 번째 엔티티: 템플릿 로드 (디스크 I/O)
resolver.resolve_entity("ui/button", overrides)?;

// 두 번째 엔티티: 캐시에서 재사용 (메모리만)
resolver.resolve_entity("ui/button", overrides)?;  // 빠름!
```

### 컴포넌트 팩토리 패턴
- 런타임 타입 체크 없이 빠른 생성
- HashMap 룩업 한 번으로 적절한 팩토리 선택

### 씬별 엔티티 추적
```rust
// O(n) 복잡도로 씬 전체 정리
for entity_id in scene_entities["old_scene"] {
    world.destroy_entity(entity_id);
}
```

## ⚠️ 주의사항

### YAML 경로
```rust
// ✅ 올바름: 상대 경로 (base_path 기준)
scene_manager.load_scene("main_menu", &world)?;
// → templates/world/scenes/main_menu.yaml

// ❌ 잘못됨: 절대 경로 사용 금지
scene_manager.load_scene("/Users/.../main_menu.yaml", &world)?;
```

### 템플릿 경로
```yaml
# ✅ 올바름: 슬래시로 구분
template: "ui/text_label"
# → world/entities/ui/text_label.yaml

# ❌ 잘못됨: 파일 확장자 포함 금지
template: "ui/text_label.yaml"
```

### 컴포넌트 이름 일치
```rust
// Factory 등록 이름과 YAML 키가 일치해야 함
registry.register("Transform", TransformFactory);

// YAML에서도 정확히 "Transform" 사용
// Transform:  ✅
// transform:  ❌ (대소문자 구분)
```

### 순환 템플릿 방지
```yaml
# ❌ 순환 참조 금지
# a.yaml: template: "b"
# b.yaml: template: "a"
# → 무한 루프 발생!
```
