文件与 Artboard
Rive .riv 文件是一个二进制容器,包含 artboards、animations、state machines、view models 和 assets。C++ API 提供了对该容器的只读访问(File、Artboard),以及可推进和绘制的可变实例(ArtboardInstance、StateMachineInstance)。
导入文件
#include "rive/file.hpp"
ImportResult result;
rcp<File> file = File::import(
Span<const uint8_t>{bytes.data(), bytes.size()},
factory, // a Factory* — usually your RenderContext
&result, // optional
assetLoader); // optional rcp<FileAssetLoader>
switch (result) {
case ImportResult::success: break;
case ImportResult::unsupportedVersion: /* runtime is older than file */ break;
case ImportResult::malformed: /* bad bytes */ break;
}
File 使用引用计数(rcp<File>)。它拥有解析后的对象图,以及以内嵌方式导入的 assets。只要仍有任何从它派生出的 artboard instance 存活,就需要保持它存活。
你传入的 Factory* 负责构造文件生成的每一个 RenderPath、RenderPaint、RenderImage、font 和 audio source。使用 Rive 的 GPU renderer 时,它通常就是你的 RenderContext。使用自定义 renderer 时,它就是你的 Factory 实现。
确定性
File::deterministicMode = true;
这是一个静态标志,会为所有后续加载强制使用固定 RNG 种子和由时间戳驱动 的滚动。适用于黄金图像测试和逐帧捕获。
查询 Artboards
size_t count = file->artboardCount();
std::string name = file->artboardNameAt(0);
Artboard* byName = file->artboard("Hero"); // by name
Artboard* byIndex = file->artboard(size_t{0}); // by index
Artboard* first = file->artboard(); // file's first artboard
这些访问器返回的 Artboard* 是只读元数据 —— 不要推进或绘制它。要播放 artboard,请创建一个实例。
实例化
// Most common: copy of the file's default artboard.
std::unique_ptr<ArtboardInstance> ab = file->artboardDefault();
// Or by name / index:
auto namedAb = file->artboardNamed("Hero");
auto indexedAb = file->artboardAt(2);
每次调用都会返回一个全新且独立的副本。你可以同时播放同一个 artboard 的多个实例 —— 每个实例都有自己的 state machine、自己的 data bindings,以及自己的 layout。
size_t anims = ab->animationCount();
size_t states = ab->stateMachineCount();
std::string animName = ab->animationNameAt(0);
std::string smName = ab->stateMachineNameAt(0);
// Designer-marked default state machine, if any.
int defaultIdx = ab->defaultStateMachineIndex(); // -1 if none
创建 State Machine
StateMachineInstance 是 C++ 中的播放单元 —— 也就是你每一帧推进、绘制,并将指针事件转发给的对象。
#include "rive/animation/state_machine_instance.hpp"
std::unique_ptr<StateMachineInstance> sm = ab->defaultStateMachine();
if (!sm && ab->stateMachineCount() > 0) {
sm = ab->stateMachineAt(0);
}
尺寸与 Layout
Artboard 具有在编辑器中设置的固有尺寸,以及可选的 layout 模式(由 Yoga 驱动)。对于非 layout fits,artboard 会保持其固有尺寸;对于 Fit::layout,则由你自行驱动 width 和 height:
#include "rive/layout.hpp"
if (fit == Fit::layout) {
ab->width(static_cast<float>(windowWidth));
ab->height(static_cast<float>(windowHeight));
} else {
ab->resetSize(); // back to intrinsic
}
// Re-evaluate layout before the next draw.
sm->advanceAndApply(0.f);
Artboard::bounds() 返回当前的 rect —— 将它传给 computeAlignment,以便将 artboard-space 映射到你的 viewport。
File 生命周期
引用计数所有权让生命周期管理变得简单:
rcp<File> file = File::import(...);
auto ab = file->artboardDefault(); // unique_ptr<ArtboardInstance>
auto sm = ab->defaultStateMachine(); // unique_ptr<StateMachineInstance>
// Tear down in reverse order:
sm.reset();
ab.reset();
file = nullptr; // last rcp drops the File
务必在销毁 RenderContext 之前销毁 Rive 对象 —— 它们持有对由该 context 拥有的 GPU resources 的引用。