Aria v1.0.0

现代 C++20 MVVM 框架 —— 跨平台、分层架构、协程优先。
一套共享核心,覆盖 Windows / macOS / Linux / iOS / Android / Web。

status: v1.0.0 C++20 MIT

English | 简体中文 (Markdown) | English HTML

为什么做这个项目

现有的 C++ MVVM 方案要么捆绑一个庞大的 UI 框架(Qt 动辄 100+ MB),要么把你锁死在单一平台上,要么藏在宏后面让你摸不着头脑。aria 走相反的路:

架构(10 个模块)

┌─────────────────────────────────────────────────────────────┐
│                     应用层 (Application)                    │
└───────────────────────────────┬─────────────────────────────┘
        ┌──────────────────┬─────┴────────────┐
        ▼                  ▼                  ▼
  ┌───────────┐      ┌───────────┐      ┌───────────┐   (可选适配器,
  │Qt6 适配器 │      │JNI 适配器 │      │HTTP 适配器│    按需启用;
  │AppKit/UIKit│     │ (Android) │      │REST/SSE Web│
  │           │      │           │      │WASM 计划中│
  └─────┬─────┘      └─────┬─────┘      └─────┬─────┘
        └──────────────────┴──────────────────┘
                           ▼
            ┌─────────────────────────────┐
            │    aria-binding (SHARED)    │
            │  BindingEngine + IViewAdapter│
            └──────────────┬──────────────┘
        ┌──────────────────┴──────────────────┐
        ▼                                     ▼
┌─────────────────┐                  ┌─────────────────┐
│ aria-runtime    │                  │  aria-async     │
│ (SHARED)        │                  │  (仅头文件)       │
│ EventBus        │                  │  Task        │
│ Container       │                  │  Scheduler      │
│ Dispatcher      │                  │  Executor       │
│ Logger          │                  │  schedule_on    │
└────────┬────────┘                  └────────┬────────┘
         └────────────────┬───────────────────┘
                          ▼
            ┌─────────────────────────────┐
            │   aria-core (仅头文件)       │
            │  Property / Computed / Cmd  │
            │  ObservableList / Validator │
            └──────────────┬──────────────┘
                           ▼
            ┌─────────────────────────────┐
            │    aria-abi (STATIC)        │
            │  类型擦除 Signal/Slot        │
            │  ABI 稳定,无模板             │
            └─────────────────────────────┘
模块类型依赖说明
aria-abiSTATIC类型擦除的信号/槽,无模板,ABI 稳定
aria-core仅头文件abi全部模板:PropertyComputedCommandObservableListValidator。仅源码兼容(非 ABI 稳定)。
aria-async仅头文件coreC++20 Task<T>、执行器。仅源码兼容。
aria-runtimeSHAREDcore, abiEventBus / Container / Dispatcher / Logger —— 单例统一放在 一个 动态库中。ABI 稳定(非模板导出)。
aria-bindingSHAREDcore, runtimeBindingEngineIViewAdapterABI 稳定(非模板导出)。
适配器SHARED/STATICbindingQt6 / AppKit / UIKit / JNI / WASM(按需启用)。

环境要求

Windows 同时支持 MSYS2 UCRT64(GCC)和 MSVC / Visual Studio 2022 两条工具链。 团队栈里有哪个就用哪个 —— 同一棵源码树都能编出完整框架 + 测试 + 适配器,不需要分支或 fork。

快速开始

git clone https://github.com/dqsjqian/aria.git
cd aria
cmake -B build
cmake --build build -j
ctest --test-dir build --output-on-failure

首次配置会通过内置的 CPM.cmake 拉取 doctest。之后全部离线可用。

一键构建脚本

# macOS / Linux
scripts/build.sh             # Release
scripts/build.sh tests       # Release + 跑测试
scripts/build.sh asan        # Debug + AddressSanitizer + UBSan
scripts/build.sh tsan        # Debug + ThreadSanitizer
scripts/build.sh clean

# Windows —— MSYS2 UCRT64(GCC + Ninja)
scripts\build.ps1            # Release
scripts\build.ps1 tests
scripts\build.ps1 asan

# Windows —— MSVC / Visual Studio 2022
scripts\build-msvc.ps1       # Release(使用 build/flavors/msvc/ 目录)
scripts\build-msvc.ps1 tests
scripts\build-msvc.ps1 debug
scripts\build-msvc.ps1 asan  # /fsanitize=address(MSVC 不带 UBSan)

Windows 工具链

aria 在 scripts/ 下提供两个并行的构建脚本,分别对应 Windows 上两条主流工具链。它们写到不同的 build 目录、互相独立,不需要互相感知。

工具链脚本构建目录备注
MSYS2 UCRT64(GCC 14+ / Clang 18+)scripts\build.ps1build/体积小(≈300 MB),大多数 CI 镜像已预装。脚本会从 C:\msys64\ucrt64\bin 等常见路径自动定位。
MSVC v143(VS 2022)scripts\build-msvc.ps1build/flavors/msvc/通过 vswhere 自动定位 VS 安装;进入 CMake 之前会先清掉 MSYS2 留下的 INCLUDE / LIB / CPATH 等环境变量;使用 Visual Studio 17 2022 生成器。

两条工具链可以来回切换、不需要 clean,build 目录互不影响。CI 每晚都会跑两条以确保不退化。

MSVC 一次性配置

# 1. 安装 Visual Studio 2022 Build Tools(或完整 IDE),勾选
#    "Desktop development with C++" + "C++ CMake tools"。
# 2. (可选)安装 Qt 6 的 msvc2022_64 组件,如果需要 Qt6 适配器 / Qt 示例。
# 3. 任意 PowerShell 窗口里:
scripts\build-msvc.ps1 tests

MSYS2 一次性配置

# 1. 从 https://www.msys2.org 安装 MSYS2
# 2. 打开 "MSYS2 UCRT64" 终端:
pacman -Syu
pacman -S --needed mingw-w64-ucrt-x86_64-toolchain `
                   mingw-w64-ucrt-x86_64-cmake `
                   mingw-w64-ucrt-x86_64-ninja git
# 3. (可选)把 C:\msys64\ucrt64\bin 加入 PATH
# 4. 从任意终端执行:
scripts\build.ps1 tests

为什么两条都支持:aria 是协程重的 C++20 代码,libstdc++、libc++ 和 MSVC STL 都能干净处理。早期只支持 MSYS2 把 .NET / Visual Studio 生态的用户挡在门外,意义不大。现在 MSVC v143 与 macOS / Ubuntu / MSYS2 走的是同一条 release 闸门

在自己的项目中使用

方式 A —— 先安装,再用 find_package(生产环境推荐)

# 在 aria 目录下:
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build -j && sudo cmake --install build
# 在你项目的 CMakeLists.txt 中:
find_package(aria 1.0 REQUIRED)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE aria::aria)
# 也可以按需选择模块:aria::core / ::async / ::runtime / ::binding

方式 B —— 直接嵌入(不安装)

add_subdirectory(third_party/aria EXCLUDE_FROM_ALL)
target_link_libraries(my_app PRIVATE aria::core aria::async)

即拷即用的模板在 templates/quickstart/

示例项目

aria 提供覆盖每一个受支持 UI 工具包的可运行示例,外加几个无界面、专门压核心的控制台示例。

UI 展示示例 —— 每个工具包一个

#项目工具包构建方式演示内容
1qt-showcaseQt6 (Widgets)CMake(ARIA_BUILD_QT6=ON总展厅 Demo:一个应用、九个 Tab,覆盖框架的每一个公开能力 —— 响应式 Property/Computed/Effect、Command、ObservableList + QAbstractListModel、Validator、Task<T> + 执行器、取消、重试、when_all、EventBus、DI Container、Dispatcher、导航、双向绑定。
2macos-appkit-mvvmmacOS AppKit (ObjC++)Xcode独立的 Xcode 项目,演示在 Objective-C++ 里使用 aria:自定义 IViewAdapter 绑定原生 NSTextField/NSButton,同一个 ViewModel 直接驱动 AppKit 控件。
3ios-oc-uikit-mvvmiOS UIKit (ObjC++)XcodeiOS 端独立 Xcode 项目:自定义 IViewAdapter 绑定原生 UILabel/UITextField/UIButton(布局走 Masonry),同一个 ViewModel 在 iPhone/iPad 上原生跑起来。
4web-mvvmWeb(HTTP/REST/SSE)CMake(ARIA_BUILD_HTTP=ONHttpAdapter 把一个 C++ ViewModel 暴露给浏览器 —— 状态经 SSE 推送、命令经 REST 触发、双向绑定,配套一个 vanilla-JS 客户端(aria_client.js)。可选 HTTPS。
5android-jni-mvvmAndroid(JNI + Compose/View)Gradle(NDK r26+)Android Studio / Gradle 工程,通过 aria-jni 适配器从 Kotlin 驱动同一个 C++ ViewModel。

无界面 / 控制台示例

ARIA_BUILD_EXAMPLES=ON(默认)时构建,无需 GUI:

项目演示内容
inspector-demoCLI 响应式图 flush 追踪器 —— 打印实时依赖图的 push/pull 轨迹(诊断 / TraceSink)。
plugin-property-demo跨 dylib 的 ABI 冒烟:宿主 exe + 插件共享库,仅通过稳定的非模板 aria::IProperty 接口跨 DSO 边界操作一个 Property<T>。以 cross_dylib_abi_smoke 测试运行。
todomvc无界面 TodoMVC:ObservableList + 两个实时 FilteredList 视图(active/completed)+ Selection,全部增量联动。以 todomvc_smoke 测试运行。

构建并运行示例 1(Qt):

cmake -S . -B build -DARIA_BUILD_QT6=ON
cmake --build build -j
./build/examples/1-qt-showcase/ex_qt_showcase

示例 4(web)需要 HTTP 适配器,运行说明见 examples/4-web-mvvm/README.md

cmake -S . -B build -DARIA_BUILD_HTTP=ON
cmake --build build --target example_4_web_mvvm

无界面示例默认随 ARIA_BUILD_EXAMPLES=ON 构建,可用 ctestcross_dylib_abi_smoketodomvc_smoke)或直接从 build/bin/ 运行。

示例 2、3 不参与 CMake 构建 —— 直接打开 Xcode 工程运行;示例 5 是 Android Studio / Gradle 工程(需 NDK r26+):

构建选项

选项默认值说明
ARIA_BUILD_TESTSON构建单元测试并注册到 ctest。
ARIA_BUILD_EXAMPLESON构建所有示例(控制台 + 启用的 Qt6 示例)。
ARIA_BUILD_BENCHMARKON构建微基准测试。
ARIA_BUILD_SHAREDONruntime/binding 编译为动态库。
ARIA_BUILD_QT6OFF构建 Qt6 适配器和 GUI 示例(需要 Qt6Widgets)。
ARIA_BUILD_APPKITOFF(已 production-grade) macOS AppKit 适配器作为一等 CMake 模块——以 STATIC + .mm 方式编译,导出 aria::adapters::appkit,完整通过 adapter_conformance 测试套件;需要 APPLE 平台。
ARIA_BUILD_UIKITOFF(已 production-grade) iOS UIKit 适配器作为一等 CMake 模块——以 STATIC + .mm 方式编译,导出 aria::adapters::uikit,在 iPhone 17 Pro Max 模拟器跑通 25/25 in-app 一致性用例;需要 APPLE 平台。
ARIA_BUILD_JNIOFFAndroid JNI 适配器,作为一等 CMake 模块——构建为 STATIC,提供 aria::adapters::jni,通过 JNI 反射调用实现与 Qt/AppKit/UIKit 相同的 IViewAdapter 契约。需要 Android NDK 工具链(NDK r26+)。
ARIA_BUILD_WASMOFF(计划中) WebAssembly 适配器。
ARIA_ENABLE_ASANOFFAddressSanitizer。
ARIA_ENABLE_UBSANOFFUndefinedBehaviorSanitizer。
ARIA_ENABLE_TSANOFFThreadSanitizer。

Hello, world

#include "aria/aria.hpp"
using namespace aria;

Property<int> count{0};

// 不再需要显式依赖列表 —— Computed 首次求值时,
// 内部读到的每一个 Property::get() 都会被自动追踪为依赖。
Computed<std::string> label([&]{
    return "count = " + std::to_string(count.get());
});

Command<> increment([&]{ count = count.get() + 1; });

auto sub = label.bind([](const std::string& s) { std::cout << s << '\n'; });

increment();   // → "count = 1"
increment();   // → "count = 2"

异步编程(C++20 协程)

#include "aria/async/task.hpp"
#include "aria/async/executor.hpp"
using namespace aria::async;

Task<std::string> fetch_user(int id) {
    co_await schedule_on(network_pool);      // 跳到工作线程
    auto raw = http::get("/users/" + std::to_string(id));
    co_await schedule_on(main_dispatcher);   // 切回 UI 线程
    co_return parse(raw);
}

跨平台映射

平台UI 宿主适配器
WindowsQt6 / WinUIaria-qt6 ✅ 可用(MSYS2 UCRT64 + MSVC 2022)
macOSAppKit / Qt6aria-qt6 ✅ 可用;AppKit ✅ 可用(示例 2)
LinuxQt6 / GTKaria-qt6 ✅ 可用
iOSUIKit / SwiftUI bridgeUIKit ✅ 可用(示例 3);aria-uikit 模块化计划中
AndroidCompose / Viewaria-jni ✅ 就绪(NDK r26+)
Web(服务端驱动)浏览器 HTML/JSaria-http ✅ 可用(REST + SSE;示例 4)
Web(浏览器内 C++)DOM via WASMaria-wasm 计划中

HTTP 适配器内置一个小型服务器(HttpAdapter),通过 JSON REST + Server-Sent-Events 协议把任意 ViewModel 暴露给浏览器,并附带一个 vanilla-JS SDK(aria_client.js)。服务端构建在仓库内置的单头文件 cpp-httplib(HTTP/1.1 + SSE)和 nlohmann::json(编解码)之上——两者都已提交到 third_party/,因此启用该适配器不引入任何新的外部构建依赖;线协议、view 注册、订阅分发与 SSE 扇出都由 aria 自己实现。它适合给桌面应用挂一个网页 UI、给无界面服务做前端、做本地调试看板等场景。WASM 适配器把 C++ 业务编进浏览器沙箱,解决的是另一类受限问题,仍在路线图上。详见 RFC 0001

当前版本已交付平台无关的核心、runtime、async 和 binding 层,全部通过单元测试。Qt6、AppKit、UIKit、JNI、HTTP 都已作为 CMake 一等可选适配器交付(受各自平台要求约束)。WASM 仍在路线图上;IViewAdapter 接口已稳定。

测试状态

$ ctest --test-dir build --output-on-failure
Test project /…/aria/build
    Start 1: abi_tests           ✅ Passed
    Start 2: core_tests          ✅ Passed
    Start 3: fuzz_tests          ✅ Passed
    Start 4: async_tests         ✅ Passed
    Start 5: runtime_tests       ✅ Passed
    Start 6: binding_tests       ✅ Passed
    Start 7: qt6_tests           ✅ Passed   (开启 ARIA_BUILD_QT6 时)
    Start 8: appkit_conformance  ✅ Passed   (Apple 平台)
    Start 9: appkit_table_source ✅ Passed   (Apple 平台)

100% tests passed, 0 tests failed(按选项最多 9 个 suites)

75+ 个测试用例分布在以上 suite 中,涵盖 docs/reference/lifecycle.mddocs/reference/error-model.md 中所有生命周期 / 重入 / 异常安全契约的回归测试。源码树还包含一个跨 dylib 的 ABI 冒烟测试(cross_dylib_abi_smoke)和一个无界面 TodoMVC(todomvc_smoke)。

性能基准(Apple M 系列, -O3 -DNDEBUG)

操作纳秒/次
Property<int>::get()10.4
Property<int>::set() 无观察者28.5
Property<int>::set() 1 个观察者29.3
Property<int>::set() 10 个观察者45.9
订阅 + 自动取消订阅周期54.9
Computed 链 x5(set + 重新计算 + get)289.1
EventBus::publish(1 个订阅者)13.4
Container::resolve<Singleton>7.6
10 次 set 包在 reactive::batch 中(只通知一次)156.1
批量更新加速比(对比逐次更新)1.91×

框架本体契约

Aria 承诺的所有非平庸行为都钉在一份带编号的契约文档里,每条契约都有一个稳定 ID(如 L-13 / E-22 / LD-7 / D-4 / S-31)——测试断言失败或 PR 评审可以直接指向权威描述。

文档前缀范围
docs/reference/api-style.mdS-N命名、命名空间、错误与异步入口的风格约束
docs/reference/lifecycle.mdL-N线程、订阅、响应式 flush、view 销毁、异步 cancel/dtor 不变式
docs/reference/error-model.mdE-Naria::Error / ErrorKind taxonomy 与各子系统错误面契约
docs/reference/list-diff-contract.mdLD-NInsert / Remove / Replace / Move / Reset / ItemChanged 语义
docs/reference/diagnostics.mdD-Naria::TraceEvent + aria::TraceSink 诊断协议
docs/reference/performance.mdPERF-N每个公开 API 的复杂度上界与实测基线

P0 硬地基 pass(详见 CHANGELOG)推平了上表所有契约;modules/core/fuzz/ 下七个框架级 fuzzer 为 lifecycle 不变式提供压力验证(默认 50k 迭代 / fuzzer;nightly 设 ARIA_FUZZ_ITERS=1000000 拉高)。

能力一览

能力类型位置
响应式状态Property<T> / Computed<T> / Effectaria/reactive/reactive.hpp
命令Command<Args...>(响应式 can_executearia/command.hpp
集合ObservableList<T> + 派生 Filtered/Sorted/Mapped/Distinct/Grouped/Pagedaria/observable_list.hpp, aria/derived/*
选择模型Selection<T> / MultiSelection<T>(SE-1..SE-5)aria/selection.hpp
校验Validator<T> / FormValidator / ValidationState + 异步规则aria/validator.hpp, aria/binding/form.hpp, aria/async/async_validator.hpp
异步Task<T> / AsyncCommand / with_timeout / when_any / when_all / CancellationTokenaria/async/*
数据拉取AsyncResource<T>(SWR + 去重)/ Loadable<T>(五态)aria/async/async_resource.hpp, aria/loadable.hpp
导航Navigatorpush/pop/push_for_result<R>、路由模式)aria/binding/navigation.hpp
绑定BindingEngine / IViewAdapter / IView / Converter / bind_view_lifetimearia/binding/*
诊断TraceEvent / TraceSink / GraphInspector(关闭时零开销)aria/diagnostics.hpp

怎么学:文档索引 串起各篇指南、Cookbook(面向任务的实操菜谱)和契约参考。用 cmake -B build -DARIA_BUILD_DOCS=ON && cmake --build build --target aria_docs 生成符号级 API 参考

路线图

Aria 不对外发版,主版本号永远停留在 1.0.0,也不维护版本演进史。待办(TODO)与已延后清单的唯一信息源在 docs/ROADMAP.md;当前能力的快照见 CHANGELOG.md

贡献指南

欢迎贡献!涉及架构改动的改动请先开 Issue 讨论。

完整的构建/测试/分层指南见 CONTRIBUTING.md

致谢

许可证

MIT © 2026 aria contributors

📖 其他格式

本文档还提供其他格式:

快速访问脚本

# 打开中文 HTML 版本
./scripts/open-readme.sh zh

# 打开英文 HTML 版本
./scripts/open-readme.sh          # 或:./scripts/open-readme.sh en

# 同时打开两个版本
./scripts/open-readme.sh all