First attempt at defaulting to statemachine
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp
index 2dfc2f5..34def2f 100644
--- a/include/rive/artboard.hpp
+++ b/include/rive/artboard.hpp
@@ -23,6 +23,7 @@
class NestedArtboard;
class ArtboardInstance;
class LinearAnimationInstance;
+ class Scene;
class StateMachineInstance;
class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer {
@@ -120,17 +121,18 @@
size_t stateMachineCount() const { return m_StateMachines.size(); }
std::string stateMachineNameAt(size_t index) const;
- LinearAnimation* firstAnimation() const;
+ LinearAnimation* firstAnimation() const { return animation(0); }
LinearAnimation* animation(const std::string& name) const;
LinearAnimation* animation(size_t index) const;
- StateMachine* firstStateMachine() const;
+ StateMachine* firstStateMachine() const { return stateMachine(0); }
StateMachine* stateMachine(const std::string& name) const;
StateMachine* stateMachine(size_t index) const;
/// When provided, the designer has specified that this artboard should
- /// always autoplay this StateMachine.
- StateMachine* defaultStateMachine() const;
+ /// always autoplay this StateMachine. Returns -1 if it was not
+ // provided.
+ int defaultStateMachineIndex() const;
/// Make an instance of this artboard, must be explictly deleted when no
/// longer needed.
@@ -164,7 +166,18 @@
std::unique_ptr<StateMachineInstance> stateMachineAt(size_t index);
std::unique_ptr<StateMachineInstance> stateMachineNamed(const std::string& name);
- std::unique_ptr<StateMachineInstance> defaultStateMachineInstance();
+
+ /// When provided, the designer has specified that this artboard should
+ /// always autoplay this StateMachine instance. If it was not specified,
+ /// this returns nullptr.
+ std::unique_ptr<StateMachineInstance> defaultStateMachine();
+
+ // This attemps to always return *something*, in this search order:
+ // 1. default statemachine instance
+ // 2. first statemachine instance
+ // 3. first animation instance
+ // 4. nullptr
+ std::unique_ptr<Scene> defaultScene();
};
} // namespace rive
diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp
index 2818f58..16d1096 100644
--- a/skia/viewer/src/main.cpp
+++ b/skia/viewer/src/main.cpp
@@ -45,6 +45,8 @@
std::vector<std::string> animationNames;
std::vector<std::string> stateMachineNames;
+constexpr int REQUEST_DEFAULT_SCENE = -1;
+
#include <time.h>
double GetSecondsToday() {
time_t m_time;
@@ -89,8 +91,6 @@
}
void initStateMachine(int index) {
- stateMachineIndex = index;
- animationIndex = -1;
assert(fileBytes.size() != 0);
auto file = rive::File::import(rive::toSpan(fileBytes), &skiaFactory);
if (!file) {
@@ -98,6 +98,9 @@
fprintf(stderr, "failed to import file\n");
return;
}
+
+ stateMachineIndex = -1;
+ animationIndex = -1;
currentScene = nullptr;
artboardInstance = nullptr;
@@ -106,8 +109,24 @@
artboardInstance->advance(0.0f);
loadNames(artboardInstance.get());
- if (index >= 0 && index < artboardInstance->stateMachineCount()) {
+ if (index < 0) {
+ currentScene = artboardInstance->defaultStateMachine();
+ index = artboardInstance->defaultStateMachineIndex();
+ }
+ if (!currentScene) {
+ if (index >= artboardInstance->stateMachineCount()) {
+ index = 0;
+ }
currentScene = artboardInstance->stateMachineAt(index);
+ }
+ if (!currentScene) {
+ index = -1;
+ currentScene = artboardInstance->animationAt(0);
+ animationIndex = 0;
+ }
+ stateMachineIndex = index;
+
+ if (currentScene) {
currentScene->inputCount();
}
}
@@ -175,7 +194,7 @@
fprintf(stderr, "failed to read all of %s\n", filename.c_str());
return;
}
- initAnimation(0);
+ initStateMachine(REQUEST_DEFAULT_SCENE);
}
int main() {
diff --git a/src/artboard.cpp b/src/artboard.cpp
index 58e9cae..349e81e 100644
--- a/src/artboard.cpp
+++ b/src/artboard.cpp
@@ -481,13 +481,6 @@
return sm ? sm->name() : nullptr;
}
-LinearAnimation* Artboard::firstAnimation() const {
- if (m_Animations.empty()) {
- return nullptr;
- }
- return m_Animations.front();
-}
-
LinearAnimation* Artboard::animation(const std::string& name) const {
for (auto animation : m_Animations) {
if (animation->name() == name) {
@@ -504,13 +497,6 @@
return m_Animations[index];
}
-StateMachine* Artboard::firstStateMachine() const {
- if (m_StateMachines.empty()) {
- return nullptr;
- }
- return m_StateMachines.front();
-}
-
StateMachine* Artboard::stateMachine(const std::string& name) const {
for (auto machine : m_StateMachines) {
if (machine->name() == name) {
@@ -527,11 +513,12 @@
return m_StateMachines[index];
}
-StateMachine* Artboard::defaultStateMachine() const {
- if (defaultStateMachineId() >= m_StateMachines.size()) {
- return nullptr;
+int Artboard::defaultStateMachineIndex() const {
+ int index = defaultStateMachineId();
+ if ((size_t)index >= m_StateMachines.size()) {
+ index = -1;
}
- return m_StateMachines[defaultStateMachineId()];
+ return index;
}
std::unique_ptr<ArtboardInstance> Artboard::instance() const {
@@ -617,7 +604,18 @@
return sm ? std::make_unique<StateMachineInstance>(sm, this) : nullptr;
}
-std::unique_ptr<StateMachineInstance> ArtboardInstance::defaultStateMachineInstance() {
- auto sm = this->defaultStateMachine();
- return sm ? std::make_unique<StateMachineInstance>(sm, this) : nullptr;
+std::unique_ptr<StateMachineInstance> ArtboardInstance::defaultStateMachine() {
+ const int index = this->defaultStateMachineIndex();
+ return index >= 0 ? this->stateMachineAt(index) : nullptr;
+}
+
+std::unique_ptr<Scene> ArtboardInstance::defaultScene() {
+ std::unique_ptr<Scene> scene = this->defaultStateMachine();
+ if (!scene) {
+ scene = this->stateMachineAt(0);
+ }
+ if (!scene) {
+ scene = this->animationAt(0);
+ }
+ return scene;
}
\ No newline at end of file
diff --git a/test/default_state_machine_test.cpp b/test/default_state_machine_test.cpp
index f9f8ff6..bfe7d1a 100644
--- a/test/default_state_machine_test.cpp
+++ b/test/default_state_machine_test.cpp
@@ -13,15 +13,19 @@
TEST_CASE("default state machine is detected at load", "[file]") {
auto file = ReadRiveFile("../../test/assets/entry.riv");
- auto artboard = file->artboard();
+ auto abi = file->artboardAt(0);
+ auto index = abi->defaultStateMachineIndex();
- REQUIRE(artboard->defaultStateMachine() != nullptr);
- REQUIRE(artboard->defaultStateMachine()->name() == "State Machine 1");
+ REQUIRE(index >= 0);
+ REQUIRE(abi->stateMachineNameAt(index) == "State Machine 1");
- auto artboardInstance = artboard->instance();
- REQUIRE(artboardInstance != nullptr);
- auto defaultStateMachineInstance = artboardInstance->defaultStateMachineInstance();
+ auto smi = abi->defaultStateMachine();
- REQUIRE(defaultStateMachineInstance != nullptr);
- REQUIRE(defaultStateMachineInstance->name() == "State Machine 1");
+ REQUIRE(smi != nullptr);
+ REQUIRE(smi->name() == "State Machine 1");
+
+ // default scene is the same as the default statemachine (when we have one)
+ auto scene = abi->defaultScene();
+ REQUIRE(scene != nullptr);
+ REQUIRE(scene->name() == smi->name());
}