Expose artboard instances directly on File
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp
index 0315a82..ad19de3 100644
--- a/include/rive/artboard.hpp
+++ b/include/rive/artboard.hpp
@@ -24,6 +24,7 @@
class NestedArtboard;
class ArtboardInstance;
class LinearAnimationInstance;
+ class StateMachineInstance;
class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer {
friend class File;
@@ -123,18 +124,23 @@
return nullptr;
}
+ size_t animationCount() const { return m_Animations.size(); }
+ std::string animationNameAt(size_t index) const;
+
+ size_t stateMachineCount() const { return m_StateMachines.size(); }
+ std::string stateMachineNameAt(size_t index) const;
+
LinearAnimation* firstAnimation() const;
LinearAnimation* animation(std::string name) const;
LinearAnimation* animation(size_t index) const;
- size_t animationCount() const { return m_Animations.size(); }
StateMachine* firstStateMachine() const;
StateMachine* stateMachine(std::string name) const;
StateMachine* stateMachine(size_t index) const;
- size_t stateMachineCount() const { return m_StateMachines.size(); }
/// Make an instance of this artboard, must be explictly deleted when no
/// longer needed.
+ // Deprecated...
std::unique_ptr<ArtboardInstance> instance() const;
/// Returns true if the artboard is an instance of another
@@ -157,6 +163,11 @@
class ArtboardInstance : public Artboard {
public:
+ std::unique_ptr<LinearAnimationInstance> animationAt(size_t index);
+ std::unique_ptr<LinearAnimationInstance> animationNamed(std::string name);
+
+ std::unique_ptr<StateMachineInstance> stateMachineAt(size_t index);
+ std::unique_ptr<StateMachineInstance> stateMachineNamed(std::string name);
};
} // namespace rive
diff --git a/include/rive/file.hpp b/include/rive/file.hpp
index 29f28e2..ab85e86 100644
--- a/include/rive/file.hpp
+++ b/include/rive/file.hpp
@@ -66,8 +66,15 @@
/// @returns the file's backboard. All files have exactly one backboard.
Backboard* backboard() const { return m_Backboard.get(); }
- /// @returns the default artboard. This is typically the first artboard
- /// found in the file's artboard list.
+ /// @returns the number of artboards in the file.
+ size_t artboardCount() const { return m_Artboards.size(); }
+ std::string artboardNameAt(size_t index) const;
+
+ // Instances
+ std::unique_ptr<ArtboardInstance> artboardDefault() const;
+ std::unique_ptr<ArtboardInstance> artboardAt(size_t index) const;
+ std::unique_ptr<ArtboardInstance> artboardNamed(std::string name) const;
+
Artboard* artboard() const;
/// @returns the named artboard. If no artboard is found with that name,
@@ -78,9 +85,6 @@
/// index is out of range.
Artboard* artboard(size_t index) const;
- /// @returns the number of artboards in the file.
- size_t artboardCount() const { return m_Artboards.size(); }
-
private:
ImportResult read(BinaryReader& reader, const RuntimeHeader& header);
};
diff --git a/skia/thumbnail_generator/src/main.cpp b/skia/thumbnail_generator/src/main.cpp
index 226b2ed..e17b9f1 100644
--- a/skia/thumbnail_generator/src/main.cpp
+++ b/skia/thumbnail_generator/src/main.cpp
@@ -55,7 +55,7 @@
fprintf(stderr, "Failed to read rive file.\n");
return 1;
}
- auto artboard = file->artboard();
+ auto artboard = file->artboardDefault();
artboard->advance(0.0f);
delete[] bytes;
diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp
index 6136e5f..d7cf24c 100644
--- a/skia/viewer/src/main.cpp
+++ b/skia/viewer/src/main.cpp
@@ -36,6 +36,13 @@
std::unique_ptr<rive::ArtboardInstance> artboardInstance;
std::unique_ptr<rive::StateMachineInstance> stateMachineInstance;
std::unique_ptr<rive::LinearAnimationInstance> animationInstance;
+
+// ImGui wants raw pointers to names, but our public API returns
+// names as strings (by value), so we cache these names each time we
+// load a file
+std::vector<std::string> animationNames;
+std::vector<std::string> stateMachineNames;
+
// We hold onto the file's bytes for the lifetime of the file, in case we want
// to change animations or state-machines, we just rebuild the rive::File from
// it.
@@ -44,6 +51,19 @@
int animationIndex = 0;
int stateMachineIndex = -1;
+static void loadNames(const rive::Artboard* ab) {
+ animationNames.clear();
+ stateMachineNames.clear();
+ if (ab) {
+ for (size_t i = 0; i < ab->animationCount(); ++i) {
+ animationNames.push_back(ab->animationNameAt(i));
+ }
+ for (size_t i = 0; i < ab->stateMachineCount(); ++i) {
+ stateMachineNames.push_back(ab->stateMachineNameAt(i));
+ }
+ }
+}
+
void initStateMachine(int index) {
stateMachineIndex = index;
animationIndex = -1;
@@ -60,11 +80,12 @@
artboardInstance = nullptr;
currentFile = std::move(file);
- artboardInstance = currentFile->artboard()->instance();
+ artboardInstance = currentFile->artboardDefault();
artboardInstance->advance(0.0f);
+ loadNames(artboardInstance.get());
if (index >= 0 && index < artboardInstance->stateMachineCount()) {
- stateMachineInstance = std::make_unique<rive::StateMachineInstance>(artboardInstance->stateMachine(index), artboardInstance.get());
+ stateMachineInstance = artboardInstance->stateMachineAt(index);
}
}
@@ -84,11 +105,12 @@
artboardInstance = nullptr;
currentFile = std::move(file);
- artboardInstance = currentFile->artboard()->instance();
+ artboardInstance = currentFile->artboardDefault();
artboardInstance->advance(0.0f);
+ loadNames(artboardInstance.get());
if (index >= 0 && index < artboardInstance->animationCount()) {
- animationInstance = std::make_unique<rive::LinearAnimationInstance>(artboardInstance->animation(index), artboardInstance.get());
+ animationInstance = artboardInstance->animationAt(index);
}
}
@@ -298,12 +320,11 @@
"Animations",
&animationIndex,
[](void* data, int index, const char** name) {
- const char* animationName = artboardInstance->animation(index)->name().c_str();
- *name = animationName;
+ *name = animationNames[index].c_str();
return true;
},
artboardInstance.get(),
- artboardInstance->animationCount(),
+ animationNames.size(),
4))
{
stateMachineIndex = -1;
@@ -313,12 +334,11 @@
"State Machines",
&stateMachineIndex,
[](void* data, int index, const char** name) {
- const char* machineName = artboardInstance->stateMachine(index)->name().c_str();
- *name = machineName;
+ *name = stateMachineNames[index].c_str();
return true;
},
artboardInstance.get(),
- artboardInstance->stateMachineCount(),
+ stateMachineNames.size(),
4))
{
animationIndex = -1;
diff --git a/src/artboard.cpp b/src/artboard.cpp
index 77d2122..7402623 100644
--- a/src/artboard.cpp
+++ b/src/artboard.cpp
@@ -450,6 +450,16 @@
return this->isTranslucent(inst->animation());
}
+std::string Artboard::animationNameAt(size_t index) const {
+ auto la = this->animation(index);
+ return la ? la->name() : nullptr;
+}
+
+std::string Artboard::stateMachineNameAt(size_t index) const {
+ auto sm = this->stateMachine(index);
+ return sm ? sm->name() : nullptr;
+}
+
LinearAnimation* Artboard::firstAnimation() const {
if (m_Animations.empty()) {
return nullptr;
@@ -609,3 +619,32 @@
return true;
}
}
+
+////////// ArtboardInstance
+
+#include "rive/animation/linear_animation_instance.hpp"
+#include "rive/animation/state_machine_instance.hpp"
+
+std::unique_ptr<LinearAnimationInstance>
+ArtboardInstance::animationAt(size_t index) {
+ auto la = this->animation(index);
+ return la ? std::make_unique<LinearAnimationInstance>(la, this) : nullptr;
+}
+
+std::unique_ptr<LinearAnimationInstance>
+ArtboardInstance::animationNamed(std::string name) {
+ auto la = this->animation(name);
+ return la ? std::make_unique<LinearAnimationInstance>(la, this) : nullptr;
+}
+
+std::unique_ptr<StateMachineInstance>
+ArtboardInstance::stateMachineAt(size_t index) {
+ auto sm = this->stateMachine(index);
+ return sm ? std::make_unique<StateMachineInstance>(sm, this) : nullptr;
+}
+
+std::unique_ptr<StateMachineInstance>
+ArtboardInstance::stateMachineNamed(std::string name) {
+ auto sm = this->stateMachine(name);
+ return sm ? std::make_unique<StateMachineInstance>(sm, this) : nullptr;
+}
diff --git a/src/file.cpp b/src/file.cpp
index eb4577d..bf5bd04 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -257,3 +257,23 @@
}
return m_Artboards[index].get();
}
+
+std::string File::artboardNameAt(size_t index) const {
+ auto ab = this->artboard(index);
+ return ab ? ab->name() : "";
+}
+
+std::unique_ptr<ArtboardInstance> File::artboardDefault() const {
+ auto ab = this->artboard();
+ return ab ? ab->instance() : nullptr;
+}
+
+std::unique_ptr<ArtboardInstance> File::artboardAt(size_t index) const {
+ auto ab = this->artboard(index);
+ return ab ? ab->instance() : nullptr;
+}
+
+std::unique_ptr<ArtboardInstance> File::artboardNamed(std::string name) const {
+ auto ab = this->artboard(name);
+ return ab ? ab->instance() : nullptr;
+}
diff --git a/test/image_mesh_test.cpp b/test/image_mesh_test.cpp
index d1575f2..6b817ed 100644
--- a/test/image_mesh_test.cpp
+++ b/test/image_mesh_test.cpp
@@ -31,9 +31,9 @@
RiveFileReader reader("../../test/assets/tape.riv");
auto file = reader.file();
- auto instance1 = file->artboard()->instance();
- auto instance2 = file->artboard()->instance();
- auto instance3 = file->artboard()->instance();
+ auto instance1 = file->artboardDefault();
+ auto instance2 = file->artboardDefault();
+ auto instance3 = file->artboardDefault();
auto node1 = instance1->find("Tape body.png");
auto node2 = instance2->find("Tape body.png");
diff --git a/test/instancing_test.cpp b/test/instancing_test.cpp
index 40fe2a5..2d8672a 100644
--- a/test/instancing_test.cpp
+++ b/test/instancing_test.cpp
@@ -50,7 +50,7 @@
REQUIRE(file->artboard() != nullptr);
REQUIRE(!file->artboard()->isInstance());
- auto artboard = file->artboard()->instance();
+ auto artboard = file->artboardDefault();
REQUIRE(artboard->isInstance());
@@ -86,7 +86,7 @@
REQUIRE(file != nullptr);
REQUIRE(file->artboard() != nullptr);
- auto artboard = file->artboard()->instance();
+ auto artboard = file->artboardDefault();
REQUIRE(file->artboard()->animationCount() == artboard->animationCount());
REQUIRE(file->artboard()->firstAnimation() == artboard->firstAnimation());