blob: 7c2e0723e82bc2192993ffb3bcec995f1ac588c4 [file] [log] [blame]
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/file_asset_resolver.hpp"
#include "rive/playable.hpp"
#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/state_machine_instance.hpp"
using namespace rive;
Playable::Playable() {}
Playable::~Playable() {}
std::unique_ptr<Playable> Playable::animationAt(File* file,
size_t artboardIndex,
size_t animationIndex) {
auto abi = file->artboardAt(artboardIndex);
if (abi) {
auto lai = abi->animationAt(animationIndex);
if (lai) {
std::unique_ptr<Playable> play(new Playable);
play->m_ABI = std::move(abi);
play->m_LAI = std::move(lai);
return play;
}
}
return nullptr;
}
std::unique_ptr<Playable> Playable::stateMachineAt(File* file,
size_t artboardIndex,
size_t machineIndex) {
auto abi = file->artboardAt(artboardIndex);
if (abi) {
auto smi = abi->stateMachineAt(machineIndex);
if (smi) {
std::unique_ptr<Playable> play(new Playable);
play->m_ABI = std::move(abi);
play->m_SMI = std::move(smi);
return play;
}
}
return nullptr;
}
std::unique_ptr<Playable> Playable::import(Span<const uint8_t> bytes,
Factory* factory,
FileAssetResolver* resolver)
{
auto file = File::import(bytes, factory, nullptr, resolver);
if (!file) {
return nullptr;
}
auto play = Playable::stateMachineAt(file.get(), 0, 0);
if (!play) {
play = Playable::animationAt(file.get(), 0, 0);
}
if (play) {
play->m_File = std::move(file);
}
return play;
}
AABB Playable::bounds() const {
return m_ABI->bounds();
}
float Playable::durationSeconds() const {
return m_SMI ? -1 : m_LAI->durationSeconds();
}
// returns true if draw() should be called
bool Playable::advance(float elapsedSeconds) {
bool needsRedraw;
if (m_SMI) {
needsRedraw = m_SMI->advance(elapsedSeconds);
} else {
needsRedraw = m_LAI->advance(elapsedSeconds);
m_LAI->apply();
}
return needsRedraw;
}
void Playable::draw(Renderer* renderer) {
m_ABI->draw(renderer);
}
void Playable::pointerEvent(Vec2D pos, PointerState state) {
if (m_SMI) {
switch (state) {
case PointerState::kDown:
m_SMI->pointerDown(pos);
break;
case PointerState::kMoved:
m_SMI->pointerMove(pos);
break;
case PointerState::kUp:
m_SMI->pointerUp(pos);
break;
}
}
// else the animation just ignores the pointer events
}
// StateMachine Inputs
size_t Playable::inputCount() const {
return m_SMI ? m_SMI->inputCount() : 0;
}
SMIInput* Playable::inputAt(size_t index) const {
return m_SMI ? m_SMI->input(index) : nullptr;
}
SMIBool* Playable::boolNamed(const std::string& name) const {
return m_SMI ? m_SMI->getBool(name) : nullptr;
}
SMINumber* Playable::numberNamed(const std::string& name) const {
return m_SMI ? m_SMI->getNumber(name) : nullptr;
}
SMITrigger* Playable::triggerNamed(const std::string& name) const {
return m_SMI ? m_SMI->getTrigger(name) : nullptr;
}