mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 11:36:25 +00:00
lottie/slot: Introduce reusable Slot API
Introduce Slot APIs for efficient slot data reuse New APIs: - uint32_t LottieAnimation::genSlot(const char* slot) - Result LottieAnimation::applySlot(uint32_t slotId) - Result LottieAnimation::delSlot(uint32_t slotId) Deprecated API: - Result override(const char* slot)
This commit is contained in:
parent
5ce6fca802
commit
6f065fc6f1
8 changed files with 280 additions and 60 deletions
|
@ -22,17 +22,6 @@ class TVG_API LottieAnimation final : public Animation
|
||||||
public:
|
public:
|
||||||
~LottieAnimation() override;
|
~LottieAnimation() override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Override Lottie properties using slot data.
|
|
||||||
*
|
|
||||||
* @param[in] slot The Lottie slot data in JSON format to override, or @c nullptr to reset.
|
|
||||||
*
|
|
||||||
* @retval Result::InsufficientCondition In case the animation is not loaded.
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
Result override(const char* slot) noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Specifies a segment by marker.
|
* @brief Specifies a segment by marker.
|
||||||
*
|
*
|
||||||
|
@ -110,6 +99,39 @@ public:
|
||||||
*/
|
*/
|
||||||
Result assign(const char* layer, uint32_t ix, const char* var, float val);
|
Result assign(const char* layer, uint32_t ix, const char* var, float val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates a new slot from the given slot data.
|
||||||
|
*
|
||||||
|
* @param[in] slot The Lottie slot data in JSON format.
|
||||||
|
*
|
||||||
|
* @retval The generated slot ID when successful, 0 otherwise.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
uint32_t genSlot(const char* slot) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Applies a previously generated slot to the animation.
|
||||||
|
*
|
||||||
|
* @param[in] slotId The ID of the slot to apply, or 0 to reset all slots.
|
||||||
|
*
|
||||||
|
* @retval Result::InsufficientCondition In case the animation is not loaded or the slot ID is invalid.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
Result applySlot(uint32_t slotId) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deletes a previously generated slot.
|
||||||
|
*
|
||||||
|
* @param[in] slotId The ID of the slot to delete, or 0 to delete all slots.
|
||||||
|
*
|
||||||
|
* @retval Result::InsufficientCondition In case the animation is not loaded or the slot ID is invalid.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
Result delSlot(uint32_t slotId) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new LottieAnimation object.
|
* @brief Creates a new LottieAnimation object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,12 +30,32 @@ LottieAnimation::LottieAnimation() = default;
|
||||||
LottieAnimation::~LottieAnimation() = default;
|
LottieAnimation::~LottieAnimation() = default;
|
||||||
|
|
||||||
|
|
||||||
Result LottieAnimation::override(const char* slot) noexcept
|
uint32_t LottieAnimation::genSlot(const char* slot) noexcept
|
||||||
|
{
|
||||||
|
auto loader = PICTURE(pImpl->picture)->loader;
|
||||||
|
if (!loader) return 0;
|
||||||
|
|
||||||
|
return static_cast<LottieLoader*>(loader)->genSlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result LottieAnimation::applySlot(uint32_t slotId) noexcept
|
||||||
{
|
{
|
||||||
auto loader = PICTURE(pImpl->picture)->loader;
|
auto loader = PICTURE(pImpl->picture)->loader;
|
||||||
if (!loader) return Result::InsufficientCondition;
|
if (!loader) return Result::InsufficientCondition;
|
||||||
|
|
||||||
if (static_cast<LottieLoader*>(loader)->override(slot)) return Result::Success;
|
if (static_cast<LottieLoader*>(loader)->applySlot(slotId)) return Result::Success;
|
||||||
|
|
||||||
|
return Result::InvalidArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result LottieAnimation::delSlot(uint32_t slotId) noexcept
|
||||||
|
{
|
||||||
|
auto loader = PICTURE(pImpl->picture)->loader;
|
||||||
|
if (!loader) return Result::InsufficientCondition;
|
||||||
|
|
||||||
|
if (static_cast<LottieLoader*>(loader)->delSlot(slotId)) return Result::Success;
|
||||||
|
|
||||||
return Result::InvalidArguments;
|
return Result::InvalidArguments;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "tvgLottieModel.h"
|
#include "tvgLottieModel.h"
|
||||||
#include "tvgLottieParser.h"
|
#include "tvgLottieParser.h"
|
||||||
#include "tvgLottieBuilder.h"
|
#include "tvgLottieBuilder.h"
|
||||||
|
#include "tvgCompressor.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
|
@ -44,7 +45,9 @@ void LottieLoader::run(unsigned tid)
|
||||||
comp = parser.comp;
|
comp = parser.comp;
|
||||||
}
|
}
|
||||||
if (parser.slots) {
|
if (parser.slots) {
|
||||||
override(parser.slots, true);
|
auto slotId = genSlot(parser.slots);
|
||||||
|
applySlot(slotId, true);
|
||||||
|
delSlot(slotId, true);
|
||||||
parser.slots = nullptr;
|
parser.slots = nullptr;
|
||||||
}
|
}
|
||||||
builder->build(comp);
|
builder->build(comp);
|
||||||
|
@ -288,45 +291,133 @@ Paint* LottieLoader::paint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LottieLoader::override(const char* slots, bool byDefault)
|
bool LottieLoader::applySlot(uint32_t slotId, bool byDefault)
|
||||||
{
|
{
|
||||||
if (!ready() || comp->slots.count == 0) return false;
|
if (!ready() || comp->slots.count == 0 || comp->slotDatas.empty()) return false;
|
||||||
|
|
||||||
//override slots
|
if (slotId == 0) {
|
||||||
if (slots) {
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
//Copy the input data because the JSON parser will encode the data immediately.
|
(*p)->reset();
|
||||||
auto temp = byDefault ? slots : duplicate(slots);
|
|
||||||
|
|
||||||
//parsing slot json
|
|
||||||
LottieParser parser(temp, dirName, builder->expressions());
|
|
||||||
parser.comp = comp;
|
|
||||||
|
|
||||||
auto idx = 0;
|
|
||||||
auto succeed = false;
|
|
||||||
while (auto sid = parser.sid(idx == 0)) {
|
|
||||||
auto applied = false;
|
|
||||||
ARRAY_FOREACH(p, comp->slots) {
|
|
||||||
if (strcmp((*p)->sid, sid)) continue;
|
|
||||||
if (parser.apply(*p, byDefault)) succeed = applied = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!applied) parser.skip();
|
|
||||||
++idx;
|
|
||||||
}
|
}
|
||||||
tvg::free((char*)temp);
|
|
||||||
rebuild = succeed;
|
|
||||||
overridden |= succeed;
|
|
||||||
return rebuild;
|
|
||||||
//reset slots
|
|
||||||
} else if (overridden) {
|
|
||||||
ARRAY_FOREACH(p, comp->slots) (*p)->reset();
|
|
||||||
overridden = false;
|
overridden = false;
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LottieSlotData* slotData = nullptr;
|
||||||
|
|
||||||
|
INLIST_FOREACH(comp->slotDatas, p) {
|
||||||
|
if (p->id == slotId) {
|
||||||
|
slotData = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slotData) return false;
|
||||||
|
|
||||||
|
ARRAY_FOREACH(p, slotData->datas) {
|
||||||
|
ARRAY_FOREACH(q, comp->slots) {
|
||||||
|
if (strcmp((*q)->sid, p->sid)) continue;
|
||||||
|
(*q)->apply(p->prop, byDefault);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overridden = true;
|
||||||
|
rebuild = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LottieLoader::delSlot(uint32_t slotId, bool byDefault)
|
||||||
|
{
|
||||||
|
if (!ready() || comp->slots.count == 0 || comp->slotDatas.empty()) return false;
|
||||||
|
|
||||||
|
if (slotId == 0) {
|
||||||
|
if (!byDefault) {
|
||||||
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
|
(*p)->reset();
|
||||||
|
}
|
||||||
|
rebuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
comp->slotDatas.free();
|
||||||
|
overridden = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LottieSlotData* slotData = nullptr;
|
||||||
|
|
||||||
|
INLIST_FOREACH(comp->slotDatas, p) {
|
||||||
|
if (p->id == slotId) {
|
||||||
|
slotData = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slotData) return false;
|
||||||
|
|
||||||
|
ARRAY_FOREACH(p, slotData->datas) {
|
||||||
|
ARRAY_FOREACH(q, comp->slots) {
|
||||||
|
if (strcmp((*q)->sid, p->sid)) continue;
|
||||||
|
if (!byDefault && (*q)->overridden) {
|
||||||
|
(*q)->reset();
|
||||||
|
rebuild = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comp->slotDatas.remove(slotData);
|
||||||
|
delete(slotData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t LottieLoader::genSlot(const char* slots)
|
||||||
|
{
|
||||||
|
if (!slots || !ready() || comp->slots.count == 0) return 0;
|
||||||
|
|
||||||
|
auto slotId = djb2Encode(slots);
|
||||||
|
INLIST_FOREACH(comp->slotDatas, p) {
|
||||||
|
if (p->id == slotId) return slotId;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto temp = duplicate(slots);
|
||||||
|
|
||||||
|
//parsing slot json
|
||||||
|
LottieParser parser(temp, dirName, builder->expressions());
|
||||||
|
parser.comp = comp;
|
||||||
|
|
||||||
|
auto idx = 0;
|
||||||
|
bool generated = false;
|
||||||
|
LottieSlotData* slotData = new LottieSlotData(slotId);
|
||||||
|
while (auto sid = parser.sid(idx == 0)) {
|
||||||
|
ARRAY_FOREACH(p, comp->slots) {
|
||||||
|
if (strcmp((*p)->sid, sid)) continue;
|
||||||
|
auto prop = parser.slotData(*p);
|
||||||
|
|
||||||
|
if (prop) {
|
||||||
|
slotData->datas.push({duplicate(sid), prop});
|
||||||
|
generated = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
tvg::free((char*)temp);
|
||||||
|
|
||||||
|
if (generated) comp->slotDatas.back(slotData);
|
||||||
|
else {
|
||||||
|
delete(slotData);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return slotData->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float LottieLoader::shorten(float frameNo)
|
float LottieLoader::shorten(float frameNo)
|
||||||
{
|
{
|
||||||
//This ensures that the target frame number is reached.
|
//This ensures that the target frame number is reached.
|
||||||
|
|
|
@ -56,7 +56,11 @@ public:
|
||||||
bool resize(Paint* paint, float w, float h) override;
|
bool resize(Paint* paint, float w, float h) override;
|
||||||
bool read() override;
|
bool read() override;
|
||||||
Paint* paint() override;
|
Paint* paint() override;
|
||||||
bool override(const char* slot, bool byDefault = false);
|
|
||||||
|
//Slot APIs
|
||||||
|
uint32_t genSlot(const char* slot);
|
||||||
|
bool applySlot(uint32_t slotId, bool byDefault = false);
|
||||||
|
bool delSlot(uint32_t slotId, bool byDefault = false);
|
||||||
|
|
||||||
//Frame Controls
|
//Frame Controls
|
||||||
bool frame(float no) override;
|
bool frame(float no) override;
|
||||||
|
|
|
@ -174,7 +174,62 @@ void LottieSlot::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LottieSlot::assign(LottieObject* target, bool byDefault)
|
LottieProperty* LottieSlot::data(LottieObject* target)
|
||||||
|
{
|
||||||
|
LottieProperty* prop = nullptr;
|
||||||
|
//apply slot object to all targets
|
||||||
|
ARRAY_FOREACH(pair, pairs) {
|
||||||
|
//backup the original properties before overwriting
|
||||||
|
switch (type) {
|
||||||
|
case LottieProperty::Type::Vector: {
|
||||||
|
prop = new LottieVector;
|
||||||
|
static_cast<LottieVector*>(prop)->copy(static_cast<LottieTransform*>(target)->position, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::Scalar: {
|
||||||
|
prop = new LottieScalar;
|
||||||
|
static_cast<LottieScalar*>(prop)->copy(static_cast<LottieTransform*>(target)->scale, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::Float: {
|
||||||
|
prop = new LottieFloat;
|
||||||
|
static_cast<LottieFloat*>(prop)->copy(static_cast<LottieTransform*>(target)->rotation, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::Opacity: {
|
||||||
|
prop = new LottieOpacity;
|
||||||
|
static_cast<LottieOpacity*>(prop)->copy(static_cast<LottieSolid*>(target)->opacity, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::Color: {
|
||||||
|
prop = new LottieColor;
|
||||||
|
static_cast<LottieColor*>(prop)->copy(static_cast<LottieSolid*>(target)->color, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::ColorStop: {
|
||||||
|
prop = new LottieColorStop;
|
||||||
|
static_cast<LottieColorStop*>(prop)->copy(static_cast<LottieGradient*>(target)->colorStops, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::TextDoc: {
|
||||||
|
prop = new LottieTextDoc;
|
||||||
|
static_cast<LottieTextDoc*>(prop)->copy(static_cast<LottieText*>(target)->doc, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LottieProperty::Type::Image: {
|
||||||
|
prop = new LottieBitmap;
|
||||||
|
static_cast<LottieBitmap*>(prop)->copy(static_cast<LottieImage*>(target)->data, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LottieSlot::apply(LottieProperty* prop, bool byDefault)
|
||||||
{
|
{
|
||||||
auto copy = !overridden && !byDefault;
|
auto copy = !overridden && !byDefault;
|
||||||
auto shallow = pairs.count == 1 ? true : false;
|
auto shallow = pairs.count == 1 ? true : false;
|
||||||
|
@ -185,22 +240,22 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LottieProperty::Type::Float: {
|
case LottieProperty::Type::Float: {
|
||||||
if (copy) pair->prop = new LottieFloat(static_cast<LottieTransform*>(pair->obj)->rotation);
|
if (copy) pair->prop = new LottieFloat(static_cast<LottieTransform*>(pair->obj)->rotation);
|
||||||
pair->obj->override(&static_cast<LottieTransform*>(target)->rotation, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Scalar: {
|
case LottieProperty::Type::Scalar: {
|
||||||
if (copy) pair->prop = new LottieScalar(static_cast<LottieTransform*>(pair->obj)->scale);
|
if (copy) pair->prop = new LottieScalar(static_cast<LottieTransform*>(pair->obj)->scale);
|
||||||
pair->obj->override(&static_cast<LottieTransform*>(target)->scale, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Vector: {
|
case LottieProperty::Type::Vector: {
|
||||||
if (copy) pair->prop = new LottieVector(static_cast<LottieTransform*>(pair->obj)->position);
|
if (copy) pair->prop = new LottieVector(static_cast<LottieTransform*>(pair->obj)->position);
|
||||||
pair->obj->override(&static_cast<LottieTransform*>(target)->position, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Color: {
|
case LottieProperty::Type::Color: {
|
||||||
if (copy) pair->prop = new LottieColor(static_cast<LottieSolid*>(pair->obj)->color);
|
if (copy) pair->prop = new LottieColor(static_cast<LottieSolid*>(pair->obj)->color);
|
||||||
pair->obj->override(&static_cast<LottieSolid*>(target)->color, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Opacity: {
|
case LottieProperty::Type::Opacity: {
|
||||||
|
@ -208,27 +263,28 @@ void LottieSlot::assign(LottieObject* target, bool byDefault)
|
||||||
if (pair->obj->type == LottieObject::Type::Transform) pair->prop = new LottieOpacity(static_cast<LottieTransform*>(pair->obj)->opacity);
|
if (pair->obj->type == LottieObject::Type::Transform) pair->prop = new LottieOpacity(static_cast<LottieTransform*>(pair->obj)->opacity);
|
||||||
else pair->prop = new LottieOpacity(static_cast<LottieSolid*>(pair->obj)->opacity);
|
else pair->prop = new LottieOpacity(static_cast<LottieSolid*>(pair->obj)->opacity);
|
||||||
}
|
}
|
||||||
pair->obj->override(&static_cast<LottieSolid*>(target)->opacity, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::ColorStop: {
|
case LottieProperty::Type::ColorStop: {
|
||||||
if (copy) pair->prop = new LottieColorStop(static_cast<LottieGradient*>(pair->obj)->colorStops);
|
if (copy) pair->prop = new LottieColorStop(static_cast<LottieGradient*>(pair->obj)->colorStops);
|
||||||
pair->obj->override(&static_cast<LottieGradient*>(target)->colorStops, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::TextDoc: {
|
case LottieProperty::Type::TextDoc: {
|
||||||
if (copy) pair->prop = new LottieTextDoc(static_cast<LottieText*>(pair->obj)->doc);
|
if (copy) pair->prop = new LottieTextDoc(static_cast<LottieText*>(pair->obj)->doc);
|
||||||
pair->obj->override(&static_cast<LottieText*>(target)->doc, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LottieProperty::Type::Image: {
|
case LottieProperty::Type::Image: {
|
||||||
if (copy) pair->prop = new LottieBitmap(static_cast<LottieImage*>(pair->obj)->data);
|
if (copy) pair->prop = new LottieBitmap(static_cast<LottieImage*>(pair->obj)->data);
|
||||||
pair->obj->override(&static_cast<LottieImage*>(target)->data, shallow, !copy);
|
pair->obj->override(prop, shallow, !copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!byDefault) overridden = true;
|
if (!byDefault) overridden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,4 +760,5 @@ LottieComposition::~LottieComposition()
|
||||||
ARRAY_FOREACH(p, fonts) delete(*p);
|
ARRAY_FOREACH(p, fonts) delete(*p);
|
||||||
ARRAY_FOREACH(p, slots) delete(*p);
|
ARRAY_FOREACH(p, slots) delete(*p);
|
||||||
ARRAY_FOREACH(p, markers) delete(*p);
|
ARRAY_FOREACH(p, markers) delete(*p);
|
||||||
|
slotDatas.free();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgStr.h"
|
#include "tvgStr.h"
|
||||||
#include "tvgCompressor.h"
|
#include "tvgCompressor.h"
|
||||||
|
#include "tvgInlist.h"
|
||||||
#include "tvgRender.h"
|
#include "tvgRender.h"
|
||||||
#include "tvgLottieProperty.h"
|
#include "tvgLottieProperty.h"
|
||||||
#include "tvgLottieRenderPooler.h"
|
#include "tvgLottieRenderPooler.h"
|
||||||
|
@ -1044,6 +1045,30 @@ struct LottieLayer : LottieGroup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct LottieSlotData
|
||||||
|
{
|
||||||
|
INLIST_ITEM(LottieSlotData);
|
||||||
|
|
||||||
|
struct SlotData {
|
||||||
|
char* sid;
|
||||||
|
LottieProperty* prop;
|
||||||
|
};
|
||||||
|
|
||||||
|
LottieSlotData(uint32_t id) : id(id) {}
|
||||||
|
|
||||||
|
~LottieSlotData()
|
||||||
|
{
|
||||||
|
ARRAY_FOREACH(p, datas) {
|
||||||
|
delete(p->prop);
|
||||||
|
tvg::free(p->sid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t id;
|
||||||
|
Array<SlotData> datas;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LottieSlot
|
struct LottieSlot
|
||||||
{
|
{
|
||||||
struct Pair {
|
struct Pair {
|
||||||
|
@ -1051,7 +1076,8 @@ struct LottieSlot
|
||||||
LottieProperty* prop;
|
LottieProperty* prop;
|
||||||
};
|
};
|
||||||
|
|
||||||
void assign(LottieObject* target, bool byDefault);
|
LottieProperty* data(LottieObject* target);
|
||||||
|
void apply(LottieProperty* prop, bool byDefault = false);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
LottieSlot(LottieLayer* layer, LottieObject* parent, char* sid, LottieObject* obj, LottieProperty::Type type) : context{layer, parent}, sid(sid), type(type)
|
LottieSlot(LottieLayer* layer, LottieObject* parent, char* sid, LottieObject* obj, LottieProperty::Type type) : context{layer, parent}, sid(sid), type(type)
|
||||||
|
@ -1131,6 +1157,7 @@ struct LottieComposition
|
||||||
Array<LottieFont*> fonts;
|
Array<LottieFont*> fonts;
|
||||||
Array<LottieSlot*> slots;
|
Array<LottieSlot*> slots;
|
||||||
Array<LottieMarker*> markers;
|
Array<LottieMarker*> markers;
|
||||||
|
Inlist<LottieSlotData> slotDatas;
|
||||||
bool expressions = false;
|
bool expressions = false;
|
||||||
bool initiated = false;
|
bool initiated = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1536,7 +1536,7 @@ const char* LottieParser::sid(bool first)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LottieParser::apply(LottieSlot* slot, bool byDefault)
|
LottieProperty* LottieParser::slotData(LottieSlot* slot)
|
||||||
{
|
{
|
||||||
enterObject();
|
enterObject();
|
||||||
|
|
||||||
|
@ -1595,14 +1595,13 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault)
|
||||||
|
|
||||||
if (!obj || Invalid()) {
|
if (!obj || Invalid()) {
|
||||||
delete(obj);
|
delete(obj);
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
slot->assign(obj, byDefault);
|
auto prop = slot->data(obj);
|
||||||
|
|
||||||
delete(obj);
|
delete(obj);
|
||||||
|
|
||||||
return true;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse();
|
bool parse();
|
||||||
bool apply(LottieSlot* slot, bool byDefault);
|
|
||||||
const char* sid(bool first = false);
|
const char* sid(bool first = false);
|
||||||
|
LottieProperty* slotData(LottieSlot* slot);
|
||||||
void captureSlots(const char* key);
|
void captureSlots(const char* key);
|
||||||
void registerSlot(LottieObject* obj, const char* sid, LottieProperty::Type type);
|
void registerSlot(LottieObject* obj, const char* sid, LottieProperty::Type type);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue