跳到主要内容

文件与 Artboard

Rive .riv 文件是一个二进制容器,包含 artboardsanimationsstate machinesview modelsassets。C++ API 提供了对该容器的只读访问(FileArtboard),以及可推进和绘制的可变实例(ArtboardInstanceStateMachineInstance)。

导入文件

#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* 负责构造文件生成的每一个 RenderPathRenderPaintRenderImage、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 的引用。