# Extra2D 模块系统

## 概述

Extra2D 采用模块化架构设计，核心功能通过**模块系统**和**服务系统**管理：

- **模块 (Module)**: 平台级初始化，管理硬件资源（窗口、渲染、输入）
- **服务 (Service)**: 运行时功能，通过服务定位器管理（场景、计时器、事件、相机）

## 架构图

```
┌─────────────────────────────────────────────────────────────┐
│                      Application                             │
│         (协调模块和服务，通过服务定位器获取依赖)               │
└─────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
┌─────────────────────────────┐   ┌─────────────────────────────┐
│         模块系统             │   │         服务系统             │
│    (Module - 硬件资源)        │   │   (Service - 运行时功能)      │
├─────────────────────────────┤   ├─────────────────────────────┤
│  ┌─────────┐ ┌─────────┐   │   │  ┌─────────┐ ┌─────────┐   │
│  │ Window  │ │ Render  │   │   │  │ Logger  │ │  Scene  │   │
│  │ Module  │ │ Module  │   │   │  │ Service │ │ Service │   │
│  │  P0     │ │  P10    │   │   │  │         │ │         │   │
│  └─────────┘ └─────────┘   │   │  └─────────┘ └─────────┘   │
│  ┌─────────┐               │   │  ┌─────────┐ ┌─────────┐   │
│  │  Input  │               │   │  │  Timer  │ │  Event  │   │
│  │ Module  │               │   │  │ Service │ │ Service │   │
│  │  P20    │               │   │  │         │ │         │   │
│  └─────────┘               │   │  └─────────┘ └─────────┘   │
│                            │   │  ┌─────────┐               │
│                            │   │  │ Camera  │               │
│                            │   │  │ Service │               │
│                            │   │  │         │               │
│                            │   │  └─────────┘               │
└─────────────────────────────┘   └─────────────────────────────┘
```

## 模块 vs 服务

| 特性 | 模块 (Module) | 服务 (Service) |
|-----|--------------|---------------|
| 用途 | 平台级初始化 | 运行时功能 |
| 生命周期 | Application 管理 | ServiceLocator 管理 |
| 依赖方式 | 通过 `deps()` 方法声明 | 通过 `ServiceLocator` 获取 |
| 可替换性 | 编译时确定 | 运行时可替换 |
| 示例 | Window, Render, Input | Scene, Timer, Event, Camera |

## 模块系统

### 模块基类

所有模块继承自 `Module` 基类：

```cpp
class Module {
public:
    virtual ~Module() = default;
    virtual bool init() = 0;                    // 初始化
    virtual void shutdown() = 0;                // 关闭
    virtual bool ok() const = 0;                // 检查状态
    virtual const char* name() const = 0;       // 模块名称
    virtual int priority() const { return 100; } // 优先级（越小越优先）
    virtual std::vector<std::type_index> deps() const { return {}; } // 依赖
    void setApp(Application* app) { app_ = app; }
    Application* app() const { return app_; }
protected:
    Application* app_ = nullptr;
};
```

### 内置模块

| 模块 | 优先级 | 依赖 | 职责 |
|-----|-------|------|------|
| WindowModule | 0 | 无 | 窗口创建和管理 |
| RenderModule | 10 | WindowModule | 渲染后端初始化 |
| InputModule | 20 | WindowModule | 输入设备管理 |

### 模块配置

每个模块有自己的配置结构：

```cpp
// Window 模块配置
struct WindowCfg {
    std::string title = "Extra2D";
    int w = 1280;
    int h = 720;
    WindowMode mode = WindowMode::Windowed;
    bool vsync = true;
    int priority = 0;
    std::string backend = "sdl2";  // "sdl2" 或 "glfw"
};

// Render 模块配置
struct RenderCfg {
    BackendType backend = BackendType::OpenGL;
    int targetFPS = 60;
    bool vsync = true;
    int multisamples = 0;
    int priority = 10;
};

// Input 模块配置
struct InputCfg {
    float deadzone = 0.15f;
    float mouseSensitivity = 1.0f;
    bool enableVibration = true;
    int maxGamepads = 4;
    int priority = 20;
};
```

### 使用模块

```cpp
Application app;

// 配置 Window 模块
app.use<WindowModule>([](auto& cfg) {
    cfg.title = "My Game";
    cfg.w = 1920;
    cfg.h = 1080;
    cfg.backend = "glfw";  // 使用 GLFW 后端
});

// 配置 Render 模块
app.use<RenderModule>([](auto& cfg) {
    cfg.backend = BackendType::OpenGL;
    cfg.vsync = true;
    cfg.targetFPS = 60;
});

// 配置 Input 模块
app.use<InputModule>([](auto& cfg) {
    cfg.deadzone = 0.2f;
    cfg.enableVibration = true;
});

app.run();
```

### 构建时选择后端

```bash
# 选择窗口后端
xmake f --window_backend=sdl2 -y   # 使用 SDL2（默认）
xmake f --window_backend=glfw -y   # 使用 GLFW

# 选择渲染后端
xmake f --render_backend=opengl -y  # 使用 OpenGL（默认）
xmake f --render_backend=vulkan -y  # 使用 Vulkan
```

## 服务系统

### 服务接口基类

```cpp
class IService {
public:
    virtual ~IService() = default;
    virtual ServiceInfo getServiceInfo() const = 0;
    virtual bool initialize() = 0;
    virtual void shutdown() = 0;
    virtual void update(float deltaTime) {}
    virtual bool isInitialized() const = 0;
};
```

### 内置服务

| 服务 | 用途 | 自动注册宏 |
|-----|------|-----------|
| LoggerService | 日志记录 | `E2D_AUTO_REGISTER_SERVICE(ILogger, ConsoleLogger)` |
| SceneService | 场景管理 | `E2D_AUTO_REGISTER_SERVICE(ISceneService, SceneService)` |
| TimerService | 计时器 | `E2D_AUTO_REGISTER_SERVICE(ITimerService, TimerService)` |
| EventService | 事件分发 | `E2D_AUTO_REGISTER_SERVICE(IEventService, EventService)` |
| CameraService | 相机系统 | `E2D_AUTO_REGISTER_SERVICE(ICameraService, CameraService)` |

### 使用服务

```cpp
// 获取服务
auto logger = app.logger();
auto sceneService = app.scenes();
auto timerService = app.timers();
auto eventService = app.events();
auto cameraService = app.camera();

// 使用日志服务
logger->info("Application started");
logger->setLevel(LogLevel::Debug);
E2D_LOG_INFO("Player position: {}, {}", x, y);
E2D_LOG_ERROR("Failed to load texture: {}", filepath);

// 使用场景服务
sceneService->pushScene(myScene);

// 使用计时器服务
timerService->addTimer(1.0f, []() {
    E2D_LOG_INFO("Timer fired!");
});

// 使用事件服务
eventService->addListener(EventType::KeyPressed, [](Event& e) {
    auto& keyEvent = std::get<KeyEvent>(e.data);
    E2D_LOG_INFO("Key pressed: {}", keyEvent.keyCode);
});

// 使用相机服务
cameraService->setPosition(100, 100);
cameraService->setZoom(2.0f);
```

## 渲染后端

### 支持的后端

| 后端 | 状态 | 平台支持 |
|-----|------|---------|
| OpenGL | 完整实现 | Windows, Linux, macOS, Switch |
| Vulkan | 计划中 | Windows, Linux, macOS, Switch |

### 渲染后端接口

```cpp
class RenderBackend {
public:
    virtual ~RenderBackend() = default;
    
    // 生命周期
    virtual bool init(IWindow* window) = 0;
    virtual void shutdown() = 0;
    
    // 帧管理
    virtual void beginFrame(const Color &clearColor) = 0;
    virtual void endFrame() = 0;
    virtual void setViewport(int x, int y, int width, int height) = 0;
    virtual void setVSync(bool enabled) = 0;
    
    // 状态设置
    virtual void setBlendMode(BlendMode mode) = 0;
    virtual void setViewProjection(const glm::mat4 &matrix) = 0;
    
    // 变换矩阵栈
    virtual void pushTransform(const glm::mat4 &transform) = 0;
    virtual void popTransform() = 0;
    virtual glm::mat4 getCurrentTransform() const = 0;
    
    // 纹理
    virtual Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels, int channels) = 0;
    virtual Ptr<Texture> loadTexture(const std::string &filepath) = 0;
    
    // 精灵批处理
    virtual void beginSpriteBatch() = 0;
    virtual void drawSprite(const Texture &texture, const Rect &destRect, const Rect &srcRect, 
                           const Color &tint, float rotation, const Vec2 &anchor) = 0;
    virtual void endSpriteBatch() = 0;
    virtual void flush() = 0;
    
    // 形状渲染
    virtual void drawLine(const Vec2 &start, const Vec2 &end, const Color &color, float width = 1.0f) = 0;
    virtual void drawRect(const Rect &rect, const Color &color, float width = 1.0f) = 0;
    virtual void fillRect(const Rect &rect, const Color &color) = 0;
    virtual void drawCircle(const Vec2 &center, float radius, const Color &color, 
                           int segments = 32, float width = 1.0f) = 0;
    virtual void fillCircle(const Vec2 &center, float radius, const Color &color, int segments = 32) = 0;
    
    // 文字渲染
    virtual Ptr<FontAtlas> createFontAtlas(const std::string &filepath, int fontSize, bool useSDF = false) = 0;
    virtual void drawText(const FontAtlas &font, const std::string &text, const Vec2 &position, const Color &color) = 0;
    
    // 工厂方法
    static UniquePtr<RenderBackend> create(BackendType type);
};
```

## 资源抽象层

渲染后端通过资源抽象层实现跨平台兼容：

```
┌─────────────────────────────────────────────────────────────┐
│                    前端 (Frontend)                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │  Renderer   │  │ SpriteBatch │  │      其他          │  │
│  └──────┬──────┘  └──────┬──────┘  └─────────────────────┘  │
└─────────┼────────────────┼──────────────────────────────────┘
          │                │
          ▼                ▼
┌─────────────────────────────────────────────────────────────┐
│              资源抽象层 (resources/)                          │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐        │
│  │  Buffer  │ │ Pipeline │ │ Framebuf │ │  Shader  │        │
│  │ (缓冲区)  │ │ (管线)   │ │(帧缓冲)  │ │ (着色器) │        │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘        │
│  ┌──────────┐ ┌──────────┐                                  │
│  │  Texture │ │ FontAtlas│                                  │
│  │ (纹理)   │ │(字体图集)│                                  │
│  └──────────┘ └──────────┘                                  │
└─────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│              后端实现 (backends/)                             │
│  ┌─────────────────┐  ┌─────────────────┐                   │
│  │     OpenGL      │  │     Vulkan      │                   │
│  │  GLBuffer       │  │  VKBuffer       │                   │
│  │  GLPipeline     │  │  VKPipeline     │                   │
│  │  GLFramebuffer  │  │  VKFramebuffer  │                   │
│  │  GLShader       │  │  VKShader       │                   │
│  │  GLTexture      │  │  VKTexture      │                   │
│  └─────────────────┘  └─────────────────┘                   │
└─────────────────────────────────────────────────────────────┘
```

## 输入事件系统

### 事件类型

```cpp
enum class EventType {
    // 键盘
    KeyPressed,
    KeyReleased,
    KeyRepeat,
    
    // 鼠标
    MouseButtonPressed,
    MouseButtonReleased,
    MouseMoved,
    MouseScrolled,
    
    // 手柄
    GamepadConnected,
    GamepadDisconnected,
    GamepadButtonPressed,
    GamepadButtonReleased,
    
    // 触摸
    TouchBegan,
    TouchMoved,
    TouchEnded,
    
    // 窗口
    WindowResize,
    WindowClose,
};
```

### 事件监听

```cpp
auto eventService = app.events();

// 监听键盘事件
eventService->addListener(EventType::KeyPressed, [](Event& e) {
    auto& key = std::get<KeyEvent>(e.data);
    E2D_LOG_INFO("Key: {}, mods: {}", key.keyCode, key.mods);
});

// 监听鼠标事件
eventService->addListener(EventType::MouseButtonPressed, [](Event& e) {
    auto& mouse = std::get<MouseButtonEvent>(e.data);
    E2D_LOG_INFO("Mouse button: {} at ({}, {})", 
                 mouse.button, mouse.position.x, mouse.position.y);
});
```

## 场景图系统

### Node 基类

```cpp
class Node : public std::enable_shared_from_this<Node> {
public:
    // 层级管理
    void addChild(Ptr<Node> child);
    void removeChild(Ptr<Node> child);
    void detach();
    void clearChildren();
    
    Ptr<Node> getParent() const;
    const std::vector<Ptr<Node>>& getChildren() const;
    
    // 变换属性
    void setPos(const Vec2& pos);
    void setRotation(float degrees);
    void setScale(const Vec2& scale);
    void setAnchor(const Vec2& anchor);
    void setOpacity(float opacity);
    void setVisible(bool visible);
    void setZOrder(int zOrder);
    
    // 世界变换
    Vec2 toWorld(const Vec2& localPos) const;
    Vec2 toLocal(const Vec2& worldPos) const;
    glm::mat4 getLocalTransform() const;
    glm::mat4 getWorldTransform() const;
    
    // 生命周期回调
    virtual void onEnter();
    virtual void onExit();
    virtual void onUpdate(float dt);
    virtual void onRender(RenderBackend& renderer);
};
```

### 使用场景

```cpp
auto scene = Scene::create();

// 创建形状节点
auto rect = ShapeNode::createFilledRect(Rect(0, 0, 100, 100), Color(1.0f, 0.4f, 0.4f, 1.0f));
auto circle = ShapeNode::createFilledCircle(Vec2(0, 0), 50, Color(0.4f, 0.4f, 1.0f, 1.0f));

// 添加到场景
scene->addChild(rect);
scene->addChild(circle);

// 运行场景
app.scenes()->runWithScene(scene);
```

## 视口适配系统

### 视口适配模式

```cpp
enum class ViewportMode {
    AspectRatio,  // 保持宽高比，可能有黑边
    Stretch,      // 拉伸填满整个窗口
    Center,       // 居中显示，不缩放
    Custom        // 自定义缩放和偏移
};
```

### 配置视口

```cpp
auto cameraService = app.camera();
if (cameraService) {
    ViewportConfig vpConfig;
    vpConfig.logicWidth = 1280.0f;
    vpConfig.logicHeight = 720.0f;
    vpConfig.mode = ViewportMode::AspectRatio;
    vpConfig.letterboxColor = Color(0.0f, 0.0f, 0.0f, 1.0f);
    
    cameraService->setViewportConfig(vpConfig);
    cameraService->updateViewport(windowWidth, windowHeight);
    cameraService->applyViewportAdapter();
}
```

## 平台支持

| 平台 | 窗口后端 | 图形 API |
|-----|---------|---------|
| Windows | SDL2 / GLFW | OpenGL / Vulkan |
| Linux | SDL2 / GLFW | OpenGL / Vulkan |
| macOS | SDL2 / GLFW | OpenGL / Vulkan |
| Nintendo Switch | SDL2 / GLFW | OpenGL / Vulkan |

## 示例

完整示例请参考：
- [examples/basic/main.cpp](../../examples/basic/main.cpp) - 基础示例
- [examples/demo_shapes/main.cpp](../../examples/demo_shapes/main.cpp) - 形状绘制
- [examples/demo_sprite/main.cpp](../../examples/demo_sprite/main.cpp) - 精灵渲染
- [examples/demo_text/main.cpp](../../examples/demo_text/main.cpp) - 文字渲染
- [examples/demo_framebuffer/main.cpp](../../examples/demo_framebuffer/main.cpp) - 帧缓冲
