Skip to content

Architecture

qingchenyouforcc edited this page Mar 11, 2026 · 6 revisions

架构概览 / Architecture

本页面介绍 NeurolingsCE 的整体代码架构和核心组件。

This page provides an overview of the NeurolingsCE codebase architecture and core components.

目录结构 / Directory Structure

NeurolingsCE/
├── src/app/                  # Qt 应用层(按职责分为 core/runtime/ui 三层)
│   ├── core/                 # 基础能力:资源加载、音效、HTTP API、压缩包导入
│   ├── runtime/              # 运行时:环境同步、导入流程、生命周期、管理器
│   └── ui/                   # 界面:管理器窗口、托盘、桌宠窗口、对话框
├── src/platform/Platform/    # 平台抽象层(Windows/Linux/macOS)
├── include/shijima-qt/       # 公共头文件(与 src/app/ 结构对应)
├── libshijima/               # [子模块] 核心看板娘模拟引擎
├── libshimejifinder/         # [子模块] 资源包导入解压
├── cpp-httplib/              # [子模块] HTTP 服务器(header-only)
├── miniz/                    # 轻量级 ZIP 库(用于 SimpleZipImporter)
├── cmake/                    # CMake 辅助脚本(BundleDefaultMascot, GenerateLicenses)
├── translations/             # i18n 翻译文件
├── src/assets/               # 内置默认看板娘精灵图 + XML 配置
├── src/packaging/            # 桌面入口、图标、.app 骨架
├── src/tools/                # Shell 辅助脚本
├── src/docs/                 # HTTP API 文档
├── src/resources/            # Windows 资源文件(.rc)+ Qt 资源(.qrc)
├── licenses/                 # 第三方许可证文本(构建时嵌入)
├── dev-docker/               # Fedora Docker 镜像(Windows 交叉编译)
└── .github/workflows/        # CI: debug (push/PR) + release (手动触发)

核心类图 / Core Class Diagram

┌─────────────────────────────────────────────────────────────────┐
│                          main.cc                                 │
│  QApplication → 单实例检查 → ShijimaManager::defaultManager()   │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                     ShijimaManager                               │
│  (PlatformWidget<QMainWindow> 单例)                              │
│                                                                   │
│  职责 / Responsibilities:                                        │
│  ├── 管理看板娘生命周期(生成、销毁、tick 循环)                  │
│  ├── 管理已加载的看板娘资源包 (MascotData)                       │
│  ├── 同步多屏幕环境信息 (environment)                            │
│  ├── 处理拖放导入                                                │
│  ├── 语言切换                                                    │
│  └── 协调 HTTP API 和窗口观察器                                  │
│                                                                   │
│  关键成员 / Key Members:                                         │
│  ├── m_mascots: list<ShijimaWidget*>    ← 活跃的看板娘实例       │
│  ├── m_loadedMascots: QMap<名称, MascotData*>                    │
│  ├── m_httpApi: ShijimaHttpApi          ← HTTP REST API          │
│  ├── m_windowObserver: ActiveWindowObserver  ← 窗口追踪          │
│  ├── m_factory: shijima::mascot::factory     ← 看板娘工厂        │
│  └── m_env: QMap<QScreen*, environment>      ← 每屏幕环境        │
└──────┬──────────┬──────────┬──────────┬────────────────────────┘
       │          │          │          │
       ▼          ▼          ▼          ▼
┌────────────┐ ┌────────┐ ┌──────────┐ ┌────────────────────┐
│ShijimaWidget│ │MascotData│ │ShijimaHttpApi│ │ActiveWindowObserver│
│(看板娘窗口) │ │(资源数据) │ │(HTTP API)    │ │(窗口追踪)          │
└────────────┘ └────────┘ └──────────┘ └────────────────────┘

核心组件详解 / Core Components

1. ShijimaManager(看板娘管理器)

文件: src/app/runtime/ 目录下的 Manager*.cc 文件 + include/shijima-qt/ShijimaManager.hpp

实现分散在多个职责切片文件中:

  • ManagerWindowSetup.cc — 管理器窗口初始化与设置
  • ManagerLifecycle.cc — 看板娘生命周期管理(spawn, kill)
  • ManagerMascotRuntime.cc — 看板娘运行时调度
  • ManagerEnvironmentSync.cc — 屏幕环境同步
  • ManagerImportWorkflow.cc — 资源包导入流程
  • ManagerTickLoop.cc — 主循环定时器

全局单例,通过 ShijimaManager::defaultManager() 访问。继承自 PlatformWidget<QMainWindow>

核心功能 / Key Functions:

方法 说明
spawn(name) 生成指定名称的看板娘实例
killAll() 销毁所有看板娘
killAllButOne(widget/name) 保留一只,销毁其余
updateEnvironment() 同步所有屏幕的环境信息(位置、大小、工作区域)
tick() 主循环回调,驱动所有看板娘的帧更新
import(path) 导入看板娘资源包
onTickSync(callback) 线程安全回调(HTTP API 线程使用)

Tick 循环 / Tick Loop:

  • 25 FPS 运行(硬编码在 libshijima 设计中)
  • 通过 QBasicTimertimerEvent() 驱动
  • 每帧:更新环境 → tick 所有看板娘 → 处理跨线程回调

线程安全 / Thread Safety:

  • std::mutex + std::condition_variable 保护跨线程操作
  • HTTP API 在独立线程运行,通过 onTickSync() 安全地在主线程执行回调

2. ShijimaWidget(看板娘窗口)

文件: src/app/ui/mascot/ 目录下的 MascotWidget*.cc 文件 + include/shijima-qt/ShijimaWidget.hpp

实现分散在多个职责切片文件中:

  • MascotWidgetRendering.cc — 渲染与绘制
  • MascotWidgetInteraction.cc — 鼠标交互与右键菜单
  • MascotWidgetTick.cc — 帧更新与状态推进

继承自 PlatformWidget<QWidget>。每个看板娘实例对应一个透明无边框窗口。

核心功能:

功能 实现
渲染 paintEvent() — 绘制当前帧精灵图,支持镜像
鼠标交互 mousePressEvent() / mouseReleaseEvent() — 拖拽和右键菜单
帧更新 tick() — 推进 libshijima 模拟状态,更新位置和图像
Hit 测试 pointInside() — 判断屏幕坐标是否在看板娘图像内
检查器 showInspector() — 打开调试信息对话框

Fall-Through 机制:

  • 追踪看板娘坠落距离(m_fallTracking
  • 当坠落超过 700 像素时启用 "穿越模式"(m_fallThroughMode),看板娘会落到屏幕最底部而非停在任务栏

缩放 / Scaling:

  • m_drawScale — 绘制缩放比例
  • 用户可通过管理器设置自定义缩放

3. MascotData(看板娘数据)

文件: src/app/core/mascot/MascotData.cc + include/shijima-qt/MascotData.hpp

封装单个看板娘资源包的数据:

属性 说明
name 看板娘名称(目录名)
path 资源包路径
behaviorsXML 行为定义 XML
actionsXML 动作定义 XML
imgRoot 图片根目录
preview 预览图标
deletable 是否可删除(默认看板娘不可删除)
id 唯一整数 ID

4. AssetLoader(资源加载器)

文件: src/app/core/assets/AssetLoader.cc + include/shijima-qt/AssetLoader.hpp

单例模式,管理看板娘精灵图的加载和缓存。

方法 说明
loadAsset(path) 加载并缓存图片资源,返回 Asset 引用
unloadAssets(root) 卸载指定根目录下的所有缓存资源

5. Asset(精灵图资源)

文件: src/app/core/assets/Asset.cc + include/shijima-qt/Asset.hpp

封装单个精灵图帧:

  • m_image / m_mirrored — 原始和镜像图像
  • m_offset — 裁剪偏移
  • m_mask / m_mirroredMask — Linux 上用于窗口区域遮罩的 QBitmap

6. ShijimaHttpApi(HTTP API)

文件: src/app/core/http/ShijimaHttpApi.cc + include/shijima-qt/ShijimaHttpApi.hpp

在独立线程启动 HTTP 服务器(默认 127.0.0.1:32456),提供 REST API 接口。

详细 API 文档见 HTTP API

7. ShijimaContextMenu(右键菜单)

文件: src/app/ui/menus/ShijimaContextMenu.cc + ContextMenuActions.cc + include/shijima-qt/ShijimaContextMenu.hpp

右键点击看板娘时弹出的上下文菜单,提供暂停、检查、分裂、关闭等操作。

8. SimpleZipImporter(ZIP 导入器)

文件: src/app/core/import/SimpleZipImporter.cc + include/shijima-qt/SimpleZipImporter.hpp

轻量级 ZIP 看板娘包导入器,基于 miniz。在 MSVC 构建中用于替代 libshimejifinder。

支持的布局:

  1. 根级actions.xml + behaviors.xml + img/ 直接在 ZIP 根目录
  2. Shimeji-ee — 包含 shimeji-ee.jar + conf/ + img/<name>/
  3. 子目录<name>/conf/actions.xml + img/
  4. 纯图片 — 只有 shime1.png ~ shime46.png(使用内置默认 XML)

9. SoundEffectManager(音效管理器)

文件: src/app/core/audio/SoundEffectManager.cc + include/shijima-qt/SoundEffectManager.hpp

可选功能(需要 SHIJIMA_USE_QTMULTIMEDIA=1),管理看板娘的音效播放。

10. PlatformWidget(平台窗口模板)

文件: include/shijima-qt/PlatformWidget.hpp

CRTP 模板类,为 QWidget / QMainWindow 添加跨平台行为:

  • ShowOnAllDesktops — 确保窗口在所有虚拟桌面上可见
  • 通过 QTimer 延迟调用 Platform::showOnAllDesktops()
// 用法
class ShijimaManager : public PlatformWidget<QMainWindow> { ... };
class ShijimaWidget : public PlatformWidget<QWidget> { ... };

数据流 / Data Flow

启动流程 / Startup Flow

main()
  │
  ├── argc > 1? → shijimaRunCli()  // CLI 模式
  │
  ├── Platform::initialize()        // 平台初始化
  ├── QApplication 创建
  │
  ├── HTTP ping 127.0.0.1:32456    // 单实例检查
  │   ├── 响应成功 → 报错退出
  │   └── 无响应 → 继续
  │
  ├── ShijimaManager::defaultManager()->show()
  │   ├── 加载默认看板娘 (DefaultMascot.cc)
  │   ├── 扫描 mascots/ 目录加载已有资源包
  │   ├── 启动 HTTP API 服务器
  │   ├── 启动窗口观察器定时器
  │   └── 启动 tick 定时器 (25 FPS)
  │
  └── app.exec()  // Qt 事件循环

Tick 循环 / Tick Loop

timerEvent() (每 40ms = 25 FPS)
  │
  ├── updateEnvironment()           // 更新屏幕/窗口信息
  │   └── m_windowObserver.tick()   // 轮询前台窗口
  │
  ├── for each ShijimaWidget:
  │   └── widget->tick()
  │       ├── m_mascot->tick()      // libshijima 状态推进
  │       ├── updateOffsets()       // 计算绘制位置
  │       └── repaint()            // 触发 paintEvent
  │
  └── 处理 tickCallbacks           // HTTP API 的线程安全回调
      └── m_tickCallbackCompletion.notify_all()

资源包导入流程 / Mascot Import Flow

用户拖拽 .zip → dropEvent()
  │
  ├── SimpleZipImporter::import()    // 或 libshimejifinder
  │   ├── 解压 ZIP
  │   ├── 识别资源包布局
  │   └── 复制到 mascots/<name>/
  │
  ├── loadData(MascotData*)          // 解析 XML 注册到工厂
  │   └── m_factory.load_template()  // libshijima 加载模板
  │
  └── refreshListWidget()            // 刷新 UI 列表

子模块关系 / Submodule Relations

代码组织约定 / Code Organization Conventions

分层结构 / Layered Structure

src/app/ 按职责分为三层:

层级 路径 职责
core src/app/core/ 基础能力:资源加载、音效、HTTP API、压缩包导入
runtime src/app/runtime/ 运行时逻辑:环境同步、导入流程、生命周期、管理器
ui src/app/ui/ 界面:管理器窗口、托盘、页面构建、桌宠窗口、对话框

实现文件命名 / Implementation File Naming

采用 "主体 + 职责" 的命名方式,将大型类拆分为多个职责切片:

命名模式 示例 说明
Manager*.cc ManagerImportWorkflow.cc ShijimaManager 的职责切片
MascotWidget*.cc MascotWidgetRendering.cc ShijimaWidget 的职责切片
ShijimaWindow*.cc ShijimaWindowBuilder.cc ShijimaManager 窗口相关

这种命名方式便于按文件名直接定位业务边界,避免单文件过大。

CLI 模式 / CLI Mode

文件: src/app/cli.cc

当传入命令行参数时 (argc > 1),程序进入 CLI 模式,通过 HTTP API 与正在运行的实例通信:

# 调用正在运行实例的 API
./NeurolingsCE <command> [args...]
NeurolingsCE (Qt App)
  │
  ├── libshijima (只读依赖 / Read-only)
  │   ├── 看板娘行为模拟引擎
  │   ├── XML 解析 (rapidxml)
  │   ├── JavaScript 脚本 (duktape)
  │   └── shijima::mascot::manager / factory / environment
  │
  ├── libshimejifinder (只读依赖 / Read-only)
  │   ├── 资源包归档解压
  │   └── 依赖 libunarr + libarchive
  │
  └── cpp-httplib (只读依赖 / Read-only)
      └── HTTP 服务器/客户端 (header-only)

注意 / Note: libshijima 不接受外部贡献(其 README 中明确声明)。作为只读依赖使用。

条件编译 / Conditional Compilation

宏 / Macro 说明
SHIJIMA_USE_QTMULTIMEDIA =1 启用音效,=0 禁用
SHIJIMA_WITH_SHIMEJIFINDER =1 启用 libshimejifinder 导入,=0 禁用
NEUROLINGSCE_VERSION 版本号字符串(如 "0.1.0"
WIN32 Windows 平台
__linux__ Linux 平台
__APPLE__ macOS 平台
NOMINMAX / WIN32_LEAN_AND_MEAN Windows 头文件精简

相关页面 / Related Pages

Clone this wiki locally