rcp file assets (#10016) ecdf58f54b

* feat: rcp_file_asset

Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
This commit is contained in:
bodymovin
2025-06-17 08:07:46 +00:00
parent 68731dce25
commit 05aa6fe2e7
22 changed files with 64 additions and 54 deletions

View File

@@ -1 +1 @@
f0da7e9f27ebc9844a6fc5f8269eb4a1072ee190
ecdf58f54bada50d90f73ab0237c8933412ca49e

View File

@@ -1,15 +1,16 @@
#ifndef _RIVE_FILE_ASSET_HPP_
#define _RIVE_FILE_ASSET_HPP_
#include "rive/assets/file_asset_referencer.hpp"
#include "rive/generated/assets/file_asset_base.hpp"
#include "rive/span.hpp"
#include "rive/refcnt.hpp"
#include "rive/simple_array.hpp"
#include <string>
namespace rive
{
class Factory;
class FileAsset : public FileAssetBase
class FileAssetReferencer;
class FileAsset : public FileAssetBase, public RefCnt<FileAsset>
{
private:
std::vector<uint8_t> m_cdnUuid;

View File

@@ -3,18 +3,18 @@
#include <vector>
#include "rive/importers/import_stack.hpp"
#include "rive/assets/file_asset.hpp"
namespace rive
{
class FileAsset;
class FileAssetReferencer
{
protected:
FileAsset* m_fileAsset = nullptr;
rcp<FileAsset> m_fileAsset;
public:
virtual ~FileAssetReferencer() = 0;
virtual void setAsset(FileAsset* asset);
virtual void setAsset(rcp<FileAsset> asset);
virtual uint32_t assetId() = 0;
StatusCode registerReferencer(ImportStack& importStack);
virtual void assetUpdated() {}

View File

@@ -10,13 +10,13 @@ class AudioEvent : public AudioEventBase, public FileAssetReferencer
{
public:
StatusCode import(ImportStack& importStack) override;
void setAsset(FileAsset* asset) override;
void setAsset(rcp<FileAsset> asset) override;
uint32_t assetId() override;
void trigger(const CallbackData& value) override;
void play();
#ifdef TESTING
AudioAsset* asset() const { return (AudioAsset*)m_fileAsset; }
AudioAsset* asset() const;
#endif
Core* clone() const override;
};

View File

@@ -14,7 +14,7 @@ public:
uint32_t propertyKey,
bool isMainDirection) override;
bool syncTargetValue(Core* target, uint32_t propertyKey) override;
ImageAsset* fileAsset();
rcp<ImageAsset> fileAsset();
protected:
DataValue* targetValue() override { return &m_targetDataValue; }

View File

@@ -83,7 +83,7 @@ public:
size_t artboardCount() const { return m_artboards.size(); }
std::string artboardNameAt(size_t index) const;
const std::vector<FileAsset*>& assets() const;
Span<const rcp<FileAsset>> assets() const;
// Instances
std::unique_ptr<ArtboardInstance> artboardDefault() const;
@@ -148,7 +148,7 @@ public:
void completeViewModelInstance(
rcp<ViewModelInstance> viewModelInstance) const;
const std::vector<DataEnum*>& enums() const;
FileAsset* asset(size_t index);
rcp<FileAsset> asset(size_t index);
std::vector<Artboard*> artboards() { return m_artboards; };
@@ -179,7 +179,7 @@ private:
Backboard* m_backboard;
/// We just keep these alive for the life of this File
std::vector<FileAsset*> m_fileAssets;
std::vector<rcp<FileAsset>> m_fileAssets;
std::vector<DataConverter*> m_DataConverters;

View File

@@ -3,6 +3,7 @@
#include "rive/importers/import_stack.hpp"
#include "rive/animation/keyframe_interpolator.hpp"
#include "rive/refcnt.hpp"
#include <unordered_map>
#include <vector>
@@ -24,7 +25,7 @@ private:
Backboard* m_Backboard;
std::unordered_map<int, Artboard*> m_ArtboardLookup;
std::vector<NestedArtboard*> m_NestedArtboards;
std::vector<FileAsset*> m_FileAssets;
std::vector<rcp<FileAsset>> m_FileAssets;
std::vector<FileAssetReferencer*> m_FileAssetReferencers;
std::vector<DataConverter*> m_DataConverters;
std::vector<DataBind*> m_DataConverterReferencers;
@@ -39,7 +40,7 @@ public:
void addArtboard(Artboard* artboard);
void addMissingArtboard();
void addNestedArtboard(NestedArtboard* artboard);
void addFileAsset(FileAsset* asset);
void addFileAsset(rcp<FileAsset> asset);
void addFileAssetReferencer(FileAssetReferencer* referencer);
void addDataConverterReferencer(DataBind* referencer);
void addDataConverter(DataConverter* converter);
@@ -48,7 +49,7 @@ public:
void addInterpolator(KeyFrameInterpolator* interpolator);
void addPhysics(ScrollPhysics* physics);
std::vector<ScrollPhysics*> physics() { return m_physics; }
std::vector<FileAsset*>* assets() { return &m_FileAssets; }
std::vector<rcp<FileAsset>>* assets() { return &m_FileAssets; }
void file(File* value);
File* file() { return m_file; };

View File

@@ -24,11 +24,11 @@ private:
public:
void setMesh(MeshDrawable* mesh);
ImageAsset* imageAsset() const { return (ImageAsset*)m_fileAsset; }
ImageAsset* imageAsset() const;
void draw(Renderer* renderer) override;
Core* hitTest(HitInfo*, const Mat2D&) override;
StatusCode import(ImportStack& importStack) override;
void setAsset(FileAsset*) override;
void setAsset(rcp<FileAsset>) override;
uint32_t assetId() override;
Core* clone() const override;
Vec2D measureLayout(float width,

View File

@@ -26,12 +26,10 @@ public:
TextStyle();
void buildDependencies() override;
const rcp<Font> font() const;
void setAsset(FileAsset*) override;
void setAsset(rcp<FileAsset>) override;
uint32_t assetId() override;
StatusCode import(ImportStack& importStack) override;
FontAsset* fontAsset() const { return (FontAsset*)m_fileAsset; }
Core* clone() const override;
void addVariation(TextStyleAxis* axis);
void addFeature(TextStyleFeature* feature);
@@ -44,6 +42,7 @@ protected:
void fontSizeChanged() override;
void lineHeightChanged() override;
void letterSpacingChanged() override;
FontAsset* fontAsset() const { return (FontAsset*)m_fileAsset.get(); }
private:
std::unique_ptr<TextVariationHelper> m_variationHelper;

View File

@@ -2,6 +2,7 @@
#define _RIVE_VIEW_MODEL_INSTANCE_ASSET_HPP_
#include "rive/generated/viewmodel/viewmodel_instance_asset_base.hpp"
#include "rive/assets/file_asset.hpp"
#include "rive/refcnt.hpp"
#include <stdio.h>
namespace rive
{
@@ -14,13 +15,13 @@ class ViewModelInstanceAsset : public ViewModelInstanceAssetBase
{
public:
StatusCode import(ImportStack& importStack) override;
void addAsset(FileAsset* asset) { m_assets.push_back(asset); }
void addAsset(rcp<FileAsset> asset) { m_assets.push_back(asset); }
protected:
const std::vector<FileAsset*>& assets() const { return m_assets; }
const std::vector<rcp<FileAsset>>& assets() const { return m_assets; }
private:
std::vector<FileAsset*> m_assets;
std::vector<rcp<FileAsset>> m_assets;
#ifdef WITH_RIVE_TOOLS
public:
void onChanged(ViewModelAssetChanged callback)

View File

@@ -2,6 +2,7 @@
#define _RIVE_VIEW_MODEL_INSTANCE_ASSET_IMAGE_HPP_
#include "rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp"
#include "rive/renderer.hpp"
#include "rive/refcnt.hpp"
#include "rive/assets/image_asset.hpp"
#include <stdio.h>
namespace rive
@@ -12,12 +13,13 @@ protected:
void propertyValueChanged() override;
public:
ViewModelInstanceAssetImage();
void value(RenderImage* image);
ImageAsset* asset() { return &m_imageAsset; }
rcp<ImageAsset> asset() { return m_imageAsset; }
Core* clone() const override;
private:
ImageAsset m_imageAsset;
rcp<ImageAsset> m_imageAsset;
};
} // namespace rive

View File

@@ -16,7 +16,7 @@ StatusCode FileAsset::import(ImportStack& importStack)
{
return StatusCode::MissingObject;
}
backboardImporter->addFileAsset(this);
backboardImporter->addFileAsset(ref_rcp(this));
return Super::import(importStack);
}

View File

@@ -26,7 +26,7 @@ StatusCode FileAssetReferencer::registerReferencer(ImportStack& importStack)
return StatusCode::Ok;
}
void FileAssetReferencer::setAsset(FileAsset* asset)
void FileAssetReferencer::setAsset(rcp<FileAsset> asset)
{
if (m_fileAsset != nullptr)
{

View File

@@ -1,6 +1,7 @@
#include "rive/assets/image_asset.hpp"
#include "rive/artboard.hpp"
#include "rive/factory.hpp"
#include "rive/assets/file_asset_referencer.hpp"
using namespace rive;

View File

@@ -9,8 +9,8 @@ using namespace rive;
void AudioEvent::play()
{
#ifdef WITH_RIVE_AUDIO
auto audioAsset = (AudioAsset*)m_fileAsset;
if (audioAsset == nullptr)
auto audioAsset = (AudioAsset*)m_fileAsset.get();
if (m_fileAsset == nullptr)
{
return;
}
@@ -62,9 +62,9 @@ StatusCode AudioEvent::import(ImportStack& importStack)
return Super::import(importStack);
}
void AudioEvent::setAsset(FileAsset* asset)
void AudioEvent::setAsset(rcp<FileAsset> asset)
{
if (asset->is<AudioAsset>())
if (asset != nullptr && asset->is<AudioAsset>())
{
FileAssetReferencer::setAsset(asset);
}
@@ -80,4 +80,8 @@ Core* AudioEvent::clone() const
return twin;
}
uint32_t AudioEvent::assetId() { return AudioEventBase::assetId(); }
uint32_t AudioEvent::assetId() { return AudioEventBase::assetId(); }
#ifdef TESTING
AudioAsset* AudioEvent::asset() const { return (AudioAsset*)m_fileAsset.get(); }
#endif

View File

@@ -10,7 +10,7 @@ DataBindContextValueAssetImage::DataBindContextValueAssetImage(
DataBindContextValue(dataBind)
{}
ImageAsset* DataBindContextValueAssetImage::fileAsset()
rcp<ImageAsset> DataBindContextValueAssetImage::fileAsset()
{
auto file = m_dataBind->file();
auto source = m_dataBind->source();
@@ -20,9 +20,9 @@ ImageAsset* DataBindContextValueAssetImage::fileAsset()
auto asset = file->asset(
source->as<ViewModelInstanceAssetImage>()->propertyValue());
if (asset != nullptr)
if (asset != nullptr && asset->is<ImageAsset>())
{
return asset->as<ImageAsset>();
return static_rcp_cast<ImageAsset>(asset);
}
}
return nullptr;

View File

@@ -175,11 +175,6 @@ File::~File()
{
delete artboard;
}
// Assets delete after artboards as they reference them.
for (auto asset : m_fileAssets)
{
delete asset;
}
for (auto& viewModel : m_ViewModels)
{
viewModel->unref();
@@ -293,7 +288,7 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header)
case AudioAsset::typeKey:
{
auto fa = object->as<FileAsset>();
m_fileAssets.push_back(fa);
m_fileAssets.push_back(rcp<FileAsset>(fa));
}
break;
case ViewModel::typeKey:
@@ -950,7 +945,7 @@ rcp<ViewModelRuntime> File::createViewModelRuntime(ViewModel* viewModel) const
return viewModelRuntime;
}
const std::vector<FileAsset*>& File::assets() const { return m_fileAssets; }
Span<const rcp<FileAsset>> File::assets() const { return m_fileAssets; }
const std::vector<DataEnum*>& File::enums() const { return m_Enums; }
@@ -1019,7 +1014,7 @@ const std::vector<uint8_t> File::stripAssets(Span<const uint8_t> bytes,
#endif
FileAsset* File::asset(size_t index)
rcp<FileAsset> File::asset(size_t index)
{
if (index >= 0 && index < m_fileAssets.size())
{

View File

@@ -26,7 +26,7 @@ void BackboardImporter::addNestedArtboard(NestedArtboard* artboard)
m_NestedArtboards.push_back(artboard);
}
void BackboardImporter::addFileAsset(FileAsset* asset)
void BackboardImporter::addFileAsset(rcp<FileAsset> asset)
{
m_FileAssets.push_back(asset);
{

View File

@@ -105,9 +105,9 @@ StatusCode Image::import(ImportStack& importStack)
// getAssetId...)
uint32_t Image::assetId() { return ImageBase::assetId(); }
void Image::setAsset(FileAsset* asset)
void Image::setAsset(rcp<FileAsset> asset)
{
if (asset->is<ImageAsset>())
if (asset != nullptr && asset->is<ImageAsset>())
{
FileAssetReferencer::setAsset(asset);
@@ -243,6 +243,8 @@ void Image::updateImageScale()
}
}
ImageAsset* Image::imageAsset() const { return (ImageAsset*)m_fileAsset.get(); }
#ifdef TESTING
#include "rive/shapes/mesh.hpp"
Mesh* Image::mesh() const { return static_cast<Mesh*>(m_Mesh); };

View File

@@ -124,7 +124,7 @@ void TextStyle::buildDependencies()
uint32_t TextStyle::assetId() { return this->fontAssetId(); }
void TextStyle::setAsset(FileAsset* asset)
void TextStyle::setAsset(rcp<FileAsset> asset)
{
if (asset->is<FontAsset>())
{

View File

@@ -8,6 +8,10 @@
using namespace rive;
ViewModelInstanceAssetImage::ViewModelInstanceAssetImage() :
m_imageAsset(rcp<ImageAsset>(new ImageAsset()))
{}
void ViewModelInstanceAssetImage::propertyValueChanged()
{
addDirt(ComponentDirt::Bindings);
@@ -23,18 +27,18 @@ void ViewModelInstanceAssetImage::propertyValueChanged()
void ViewModelInstanceAssetImage::value(RenderImage* image)
{
propertyValue(-1);
if (m_imageAsset.renderImage() == image)
if (m_imageAsset->renderImage() == image)
{
return;
}
if (image == nullptr)
{
m_imageAsset.renderImage(nullptr);
m_imageAsset->renderImage(nullptr);
}
else
{
image->ref();
m_imageAsset.renderImage(rcp<RenderImage>(image));
m_imageAsset->renderImage(rcp<RenderImage>(image));
}
addDirt(ComponentDirt::Bindings);
}

View File

@@ -76,18 +76,18 @@ TEST_CASE("Test data binding images from file assets", "[data binding]")
REQUIRE(sub1Image != nullptr);
// Validations
// Ensure view model image asset is the same as the image's image asset
auto mainAsset = assets[mainImgProperty->propertyValue()];
auto mainAsset = assets[mainImgProperty->propertyValue()].get();
auto imageAsset = rootImage->imageAsset();
REQUIRE(imageAsset == mainAsset);
auto sub1Asset = assets[sub1ImgProperty->propertyValue()];
auto sub1Asset = assets[sub1ImgProperty->propertyValue()].get();
auto sub1ImageAsset = sub1Image->imageAsset();
REQUIRE(sub1Asset == sub1ImageAsset);
// Change values
mainImgProperty->propertyValue(2);
sub1ImgProperty->propertyValue(6);
artboard->advance(0.0f);
auto updatedMainAsset = assets[mainImgProperty->propertyValue()];
auto updatedSub1Asset = assets[sub1ImgProperty->propertyValue()];
auto updatedMainAsset = assets[mainImgProperty->propertyValue()].get();
auto updatedSub1Asset = assets[sub1ImgProperty->propertyValue()].get();
// Ensure image is no longer the same
REQUIRE(imageAsset != updatedMainAsset);
REQUIRE(sub1ImageAsset != updatedSub1Asset);