Make nested artboard ownership clearer
diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp
index 76cb46a..71e1c13 100644
--- a/include/rive/nested_artboard.hpp
+++ b/include/rive/nested_artboard.hpp
@@ -6,14 +6,17 @@
#include <stdio.h>
namespace rive {
+ class ArtboardInstance;
class NestedAnimation;
class NestedArtboard : public NestedArtboardBase {
private:
- Artboard* m_NestedInstance = nullptr;
+ Artboard* m_Artboard = nullptr; // might point to m_Instance, and might not
+ std::unique_ptr<ArtboardInstance> m_Instance; // may be null
std::vector<NestedAnimation*> m_NestedAnimations;
public:
+ NestedArtboard();
~NestedArtboard();
StatusCode onAddedClean(CoreContext* context) override;
void draw(Renderer* renderer) override;
diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp
index 5eec148..6bd13d8 100644
--- a/src/nested_artboard.cpp
+++ b/src/nested_artboard.cpp
@@ -7,26 +7,28 @@
using namespace rive;
-NestedArtboard::~NestedArtboard() {
- if (m_NestedInstance->isInstance()) {
- delete m_NestedInstance;
- }
-}
+NestedArtboard::NestedArtboard() {}
+NestedArtboard::~NestedArtboard() {}
+
Core* NestedArtboard::clone() const {
NestedArtboard* nestedArtboard = static_cast<NestedArtboard*>(NestedArtboardBase::clone());
- if (m_NestedInstance == nullptr) {
+ if (m_Artboard == nullptr) {
return nestedArtboard;
}
- auto ni = m_NestedInstance->instance();
- assert(ni->isInstance());
+ auto ni = m_Artboard->instance();
nestedArtboard->nest(ni.release());
return nestedArtboard;
}
void NestedArtboard::nest(Artboard* artboard) {
assert(artboard != nullptr);
- m_NestedInstance = artboard;
- m_NestedInstance->advance(0.0f);
+
+ m_Artboard = artboard;
+ m_Instance = nullptr;
+ if (artboard->isInstance()) {
+ m_Instance.reset(static_cast<ArtboardInstance*>(artboard)); // take ownership
+ }
+ m_Artboard->advance(0.0f);
}
static Mat2D makeTranslate(const Artboard* artboard) {
@@ -35,7 +37,7 @@
}
void NestedArtboard::draw(Renderer* renderer) {
- if (m_NestedInstance == nullptr) {
+ if (m_Artboard == nullptr) {
return;
}
if (!clip(renderer)) {
@@ -43,18 +45,18 @@
// transformations.
renderer->save();
}
- renderer->transform(worldTransform() * makeTranslate(m_NestedInstance));
- m_NestedInstance->draw(renderer);
+ renderer->transform(worldTransform() * makeTranslate(m_Artboard));
+ m_Artboard->draw(renderer);
renderer->restore();
}
Core* NestedArtboard::hitTest(HitInfo* hinfo, const Mat2D& xform) {
- if (m_NestedInstance == nullptr) {
+ if (m_Artboard == nullptr) {
return nullptr;
}
hinfo->mounts.push_back(this);
- auto mx = xform * worldTransform() * makeTranslate(m_NestedInstance);
- if (auto c = m_NestedInstance->hitTest(hinfo, &mx)) {
+ auto mx = xform * worldTransform() * makeTranslate(m_Artboard);
+ if (auto c = m_Artboard->hitTest(hinfo, &mx)) {
return c;
}
hinfo->mounts.pop_back();
@@ -82,30 +84,29 @@
// does require that we always use an artboard instance (not just the source
// artboard) when working with nested artboards, but in general this is good
// practice for any loaded Rive file.
- assert(m_NestedInstance == nullptr || m_NestedInstance->isInstance());
+ assert(m_Artboard == nullptr || m_Artboard == m_Instance.get());
- if (m_NestedInstance != nullptr && m_NestedInstance->isInstance()) {
- auto abi = static_cast<ArtboardInstance*>(m_NestedInstance);
+ if (m_Instance) {
for (auto animation : m_NestedAnimations) {
- animation->initializeAnimation(abi);
+ animation->initializeAnimation(m_Instance.get());
}
}
return Super::onAddedClean(context);
}
bool NestedArtboard::advance(float elapsedSeconds) {
- if (m_NestedInstance == nullptr) {
+ if (m_Artboard == nullptr) {
return false;
}
for (auto animation : m_NestedAnimations) {
animation->advance(elapsedSeconds);
}
- return m_NestedInstance->advance(elapsedSeconds);
+ return m_Artboard->advance(elapsedSeconds);
}
void NestedArtboard::update(ComponentDirt value) {
Super::update(value);
- if (hasDirt(value, ComponentDirt::WorldTransform) && m_NestedInstance != nullptr) {
- m_NestedInstance->opacity(renderOpacity());
+ if (hasDirt(value, ComponentDirt::WorldTransform) && m_Artboard != nullptr) {
+ m_Artboard->opacity(renderOpacity());
}
}