WIP: use rcp for instances
diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index 4c02e0b..b1ff906 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp
@@ -19,7 +19,7 @@ int m_LoopValue = -1; public: - LinearAnimationInstance(const LinearAnimation*, ArtboardInstance*); + LinearAnimationInstance(const LinearAnimation*, rcp<ArtboardInstance>); // Advance the animation by the specified time. Returns true if the // animation will continue to animate after this advance. @@ -52,7 +52,7 @@ // between 0 and 1) is the strength at which the animation is mixed with // other animations applied to the artboard. void apply(float mix = 1.0f) const { - m_Animation->apply(m_ArtboardInstance, m_Time, mix); + m_Animation->apply(m_ArtboardInstance.get(), m_Time, mix); } // Set when the animation is advanced, true if the animation has stopped
diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index fa8fe6f..16044a5 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp
@@ -45,7 +45,7 @@ InstType* getNamedInput(const std::string& name) const; public: - StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); + StateMachineInstance(const StateMachine* machine, rcp<ArtboardInstance>); ~StateMachineInstance() override; // Advance the state machine by the specified time. Returns true if the
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index f7cb07b..86fd8af 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp
@@ -32,6 +32,7 @@ friend class Component; private: + File* m_File; std::vector<Core*> m_Objects; std::vector<LinearAnimation*> m_Animations; std::vector<StateMachine*> m_StateMachines; @@ -63,7 +64,7 @@ void addNestedArtboard(NestedArtboard* object); public: - Artboard() {} + Artboard(File* file) : m_File(file) {} ~Artboard(); StatusCode initialize(); @@ -158,9 +159,11 @@ StatusCode import(ImportStack& importStack) override; }; - class ArtboardInstance : public Artboard { + class ArtboardInstance : public Artboard, public RefCnt { + rcp<File> m_File; + public: - ArtboardInstance() {} + ArtboardInstance(rcp<File> file); std::unique_ptr<LinearAnimationInstance> animationAt(size_t index); std::unique_ptr<LinearAnimationInstance> animationNamed(const std::string& name);
diff --git a/include/rive/file.hpp b/include/rive/file.hpp index 9d2ea3f..4fb579e 100644 --- a/include/rive/file.hpp +++ b/include/rive/file.hpp
@@ -1,6 +1,7 @@ #ifndef _RIVE_FILE_HPP_ #define _RIVE_FILE_HPP_ +#include "rive/refcnt.hpp" #include "rive/artboard.hpp" #include "rive/backboard.hpp" #include "rive/factory.hpp" @@ -30,7 +31,7 @@ /// /// A Rive file. /// - class File { + class File : public RefCnt { public: /// Major version number supported by the runtime. static const int majorVersion = 7;
diff --git a/include/rive/refcnt.hpp b/include/rive/refcnt.hpp index 67bbcfb..c61390a 100644 --- a/include/rive/refcnt.hpp +++ b/include/rive/refcnt.hpp
@@ -161,6 +161,14 @@ return a.get() != b.get(); } + template <typename T> rcp<T> rive_ref_sp(T* obj) { + return rcp<T>(safe_ref(obj)); + } + + template <typename T> rcp<T> rive_ref_sp(const T* obj) { + return rcp<T>(const_cast<T*>(safe_ref(obj))); +} + } // namespace rive #endif
diff --git a/include/rive/scene.hpp b/include/rive/scene.hpp index 90de466..58c2f17 100644 --- a/include/rive/scene.hpp +++ b/include/rive/scene.hpp
@@ -1,6 +1,7 @@ #ifndef _RIVE_SCENE_HPP_ #define _RIVE_SCENE_HPP_ +#include "rive/refcnt.hpp" #include "rive/animation/loop.hpp" #include "rive/math/aabb.hpp" #include "rive/math/vec2d.hpp" @@ -17,12 +18,12 @@ class Scene { protected: - ArtboardInstance* m_ArtboardInstance; + rcp<ArtboardInstance> m_ArtboardInstance; - Scene(ArtboardInstance*); + Scene(rcp<ArtboardInstance>); public: - virtual ~Scene() {} + virtual ~Scene(); float width() const; float height() const;
diff --git a/src/artboard.cpp b/src/artboard.cpp index 0a099ba..8c501cc 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp
@@ -7,6 +7,7 @@ #include "rive/draw_target.hpp" #include "rive/draw_target_placement.hpp" #include "rive/drawable.hpp" +#include "rive/file.hpp" #include "rive/animation/keyed_object.hpp" #include "rive/node.hpp" #include "rive/renderer.hpp" @@ -522,7 +523,7 @@ } std::unique_ptr<ArtboardInstance> Artboard::instance() const { - std::unique_ptr<ArtboardInstance> artboardClone(new ArtboardInstance); + std::unique_ptr<ArtboardInstance> artboardClone(new ArtboardInstance(rive_ref_sp(m_File))); artboardClone->copy(*this); artboardClone->m_Factory = m_Factory; @@ -584,24 +585,29 @@ #include "rive/animation/linear_animation_instance.hpp" #include "rive/animation/state_machine_instance.hpp" +ArtboardInstance::ArtboardInstance(rcp<File> file) : + Artboard(file.get()), + m_File(std::move(file)) +{} + std::unique_ptr<LinearAnimationInstance> ArtboardInstance::animationAt(size_t index) { auto la = this->animation(index); - return la ? std::make_unique<LinearAnimationInstance>(la, this) : nullptr; + return la ? std::make_unique<LinearAnimationInstance>(la, rive_ref_sp(this)) : nullptr; } std::unique_ptr<LinearAnimationInstance> ArtboardInstance::animationNamed(const std::string& name) { auto la = this->animation(name); - return la ? std::make_unique<LinearAnimationInstance>(la, this) : nullptr; + return la ? std::make_unique<LinearAnimationInstance>(la, rive_ref_sp(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; + return sm ? std::make_unique<StateMachineInstance>(sm, rive_ref_sp(this)) : nullptr; } std::unique_ptr<StateMachineInstance> ArtboardInstance::stateMachineNamed(const std::string& name) { auto sm = this->stateMachine(name); - return sm ? std::make_unique<StateMachineInstance>(sm, this) : nullptr; + return sm ? std::make_unique<StateMachineInstance>(sm, rive_ref_sp(this)) : nullptr; } std::unique_ptr<StateMachineInstance> ArtboardInstance::defaultStateMachine() {
diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index bbd543d..458b81d 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp
@@ -1,6 +1,7 @@ #include "rive/nested_artboard.hpp" #include "rive/artboard.hpp" #include "rive/backboard.hpp" +#include "rive/file.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/backboard_importer.hpp" #include "rive/nested_animation.hpp"
diff --git a/test/file_test.cpp b/test/file_test.cpp index b8cd48b..1440881 100644 --- a/test/file_test.cpp +++ b/test/file_test.cpp
@@ -124,6 +124,53 @@ REQUIRE(artboard->objects().size() == 7); } +const char* gRivFileNames[] = { + "blend_test.riv", + "bullet_man.riv", + "circle_clips.riv", + "complex_ik_dependency.riv", + "dependency_test.riv", + "distance_constraint.riv", + "draw_rule_cycle.riv", + "entry.riv", + "fix_rectangle.riv", + "juice.riv", + "light_switch.riv", + "long_name.riv", + "multiple_state_machines.riv", + "off_road_car.riv", + "out_of_band", + "rocket.riv", + "rotation_constraint.riv", + "scale_constraint.riv", + "shapetest.riv", + "stroke_name_test.riv", + "tape.riv", + "transform_constraint.riv", + "translation_constraint.riv", + "trim_path_linear.riv", + "two_artboards.riv", + "two_bone_ik.riv", + "walle.riv", +}; + +TEST_CASE("bookkeeping for files and artboard instances", "[file]") { + for (auto name : gRivFileNames) { + std::string path("../../test/assets/") + name; + auto file = ReadRiveFile(path.c_str()); + auto abi = file->artboardAt(0); + file = nullptr; // unref the file, but abi should still be an owner + + auto anim = abi->animationAt(0); + abi = nillptr; // unref the artboardinstance, but anim should still be an owner + + anim->advanceAndApply(0); + + rive::NoOpRenderer renderer; + anim->draw(&renderer); + } +} + // TODO: // ShapePaint (fill/stroke) needs to be implemented in WASM (jsFill/jsStroke) in // order to create Paint objects as necessary.
diff --git a/test/files.txt b/test/files.txt new file mode 100644 index 0000000..9a44337 --- /dev/null +++ b/test/files.txt
@@ -0,0 +1,27 @@ +blend_test.riv +bullet_man.riv +circle_clips.riv +complex_ik_dependency.riv +dependency_test.riv +distance_constraint.riv +draw_rule_cycle.riv +entry.riv +fix_rectangle.riv +juice.riv +light_switch.riv +long_name.riv +multiple_state_machines.riv +off_road_car.riv +out_of_band +rocket.riv +rotation_constraint.riv +scale_constraint.riv +shapetest.riv +stroke_name_test.riv +tape.riv +transform_constraint.riv +translation_constraint.riv +trim_path_linear.riv +two_artboards.riv +two_bone_ik.riv +walle.riv