diff --git a/.rive_head b/.rive_head index fb5018fa..5cb2d554 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -6c5c79b751c50fa4393fb0e44624635861bc3f3b +49cabe3cbd9c9683bd704e0d72a455d698bfe061 diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json index eaf9be27..c93b559c 100644 --- a/dev/defs/data_bind/data_bind.json +++ b/dev/defs/data_bind/data_bind.json @@ -26,15 +26,13 @@ }, "description": "The property that is targeted." }, - "modeValue": { + "flags": { "type": "uint", - "typeRuntime": "uint", "initialValue": "0", "key": { "int": 587, - "string": "modevalue" - }, - "description": "Backing enum value for the binding mode." + "string": "flags" + } } } } \ No newline at end of file diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp index 113b7fb3..a6bdd46b 100644 --- a/include/rive/data_bind/data_bind_context.hpp +++ b/include/rive/data_bind/data_bind_context.hpp @@ -13,11 +13,9 @@ class DataBindContext : public DataBindContextBase std::vector m_SourcePathIdsBuffer; public: - void update(ComponentDirt value) override; void decodeSourcePathIds(Span value) override; void copySourcePathIds(const DataBindContextBase& object) override; void bind() override; - void updateSourceBinding() override; ViewModelInstanceValue* source() { return m_Source; }; }; } // namespace rive diff --git a/include/rive/data_bind/data_bind_mode.hpp b/include/rive/data_bind/data_bind_mode.hpp deleted file mode 100644 index 692e62dc..00000000 --- a/include/rive/data_bind/data_bind_mode.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _RIVE_DATA_BIND_MODE_HPP_ -#define _RIVE_DATA_BIND_MODE_HPP_ -namespace rive -{ -enum class DataBindMode : unsigned int -{ - oneWay = 0, - twoWay = 1, - oneWayToSource = 2, - once = 3, -}; -} -#endif \ No newline at end of file diff --git a/include/rive/data_bind_flags.hpp b/include/rive/data_bind_flags.hpp new file mode 100644 index 00000000..2d8561fd --- /dev/null +++ b/include/rive/data_bind_flags.hpp @@ -0,0 +1,29 @@ +#ifndef _RIVE_DATA_BIND_FLAGS_HPP_ +#define _RIVE_DATA_BIND_FLAGS_HPP_ + +#include "rive/enum_bitset.hpp" + +namespace rive +{ +enum class DataBindFlags : unsigned short +{ + /// Whether the main binding direction is to source (0) or to target (1) + Direction = 1 << 0, + + /// Whether the binding direction is twoWay + TwoWay = 1 << 1, + + /// Whether the binding happens only once + Once = 1 << 2, + + /// Flag if set to target + ToTarget = 0, + + /// Flag if set to source + ToSource = 1 << 0, + +}; + +RIVE_MAKE_ENUM_BITSET(DataBindFlags) +} // namespace rive +#endif diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 519c0641..eb3a240c 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -926,8 +926,8 @@ class CoreRegistry case DataBindBase::propertyKeyPropertyKey: object->as()->propertyKey(value); break; - case DataBindBase::modeValuePropertyKey: - object->as()->modeValue(value); + case DataBindBase::flagsPropertyKey: + object->as()->flags(value); break; case WeightBase::valuesPropertyKey: object->as()->values(value); @@ -1884,8 +1884,8 @@ class CoreRegistry return object->as()->targetId(); case DataBindBase::propertyKeyPropertyKey: return object->as()->propertyKey(); - case DataBindBase::modeValuePropertyKey: - return object->as()->modeValue(); + case DataBindBase::flagsPropertyKey: + return object->as()->flags(); case WeightBase::valuesPropertyKey: return object->as()->values(); case WeightBase::indicesPropertyKey: @@ -2472,7 +2472,7 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: case DataBindBase::targetIdPropertyKey: case DataBindBase::propertyKeyPropertyKey: - case DataBindBase::modeValuePropertyKey: + case DataBindBase::flagsPropertyKey: case WeightBase::valuesPropertyKey: case WeightBase::indicesPropertyKey: case TendonBase::boneIdPropertyKey: @@ -3010,7 +3010,7 @@ class CoreRegistry return object->is(); case DataBindBase::propertyKeyPropertyKey: return object->is(); - case DataBindBase::modeValuePropertyKey: + case DataBindBase::flagsPropertyKey: return object->is(); case WeightBase::valuesPropertyKey: return object->is(); diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp index ed0d48db..4c73ffc4 100644 --- a/include/rive/generated/data_bind/data_bind_base.hpp +++ b/include/rive/generated/data_bind/data_bind_base.hpp @@ -30,12 +30,12 @@ class DataBindBase : public Component static const uint16_t targetIdPropertyKey = 585; static const uint16_t propertyKeyPropertyKey = 586; - static const uint16_t modeValuePropertyKey = 587; + static const uint16_t flagsPropertyKey = 587; private: uint32_t m_TargetId = -1; uint32_t m_PropertyKey = Core::invalidPropertyKey; - uint32_t m_ModeValue = 0; + uint32_t m_Flags = 0; public: inline uint32_t targetId() const { return m_TargetId; } @@ -60,15 +60,15 @@ class DataBindBase : public Component propertyKeyChanged(); } - inline uint32_t modeValue() const { return m_ModeValue; } - void modeValue(uint32_t value) + inline uint32_t flags() const { return m_Flags; } + void flags(uint32_t value) { - if (m_ModeValue == value) + if (m_Flags == value) { return; } - m_ModeValue = value; - modeValueChanged(); + m_Flags = value; + flagsChanged(); } Core* clone() const override; @@ -76,7 +76,7 @@ class DataBindBase : public Component { m_TargetId = object.m_TargetId; m_PropertyKey = object.m_PropertyKey; - m_ModeValue = object.m_ModeValue; + m_Flags = object.m_Flags; Component::copy(object); } @@ -90,8 +90,8 @@ class DataBindBase : public Component case propertyKeyPropertyKey: m_PropertyKey = CoreUintType::deserialize(reader); return true; - case modeValuePropertyKey: - m_ModeValue = CoreUintType::deserialize(reader); + case flagsPropertyKey: + m_Flags = CoreUintType::deserialize(reader); return true; } return Component::deserialize(propertyKey, reader); @@ -100,7 +100,7 @@ class DataBindBase : public Component protected: virtual void targetIdChanged() {} virtual void propertyKeyChanged() {} - virtual void modeValueChanged() {} + virtual void flagsChanged() {} }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index a72cba26..47c5d045 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -4,7 +4,6 @@ #include "rive/dependency_sorter.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" #include "rive/audio_event.hpp" @@ -18,6 +17,7 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/nested_artboard.hpp" #include "rive/joystick.hpp" +#include "rive/data_bind_flags.hpp" #include "rive/animation/nested_bool.hpp" #include "rive/animation/nested_number.hpp" #include "rive/animation/nested_trigger.hpp" @@ -1050,16 +1050,19 @@ void Artboard::buildDataBindDependencies(std::vector* dataBinds) for (auto component : *dataBinds) { auto dataBind = component->as(); - auto mode = static_cast(dataBind->modeValue()); + auto flags = static_cast(dataBind->flags()); // If the data bind reads from the target, we want to add it as dependent from any other - // data bind that writes into that target. - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + // parent data bind that writes into that target. + if (((flags & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { for (auto innerComponent : *dataBinds) { auto dataBindParent = innerComponent->as(); - auto parentMode = static_cast(dataBind->modeValue()); - if (dataBindParent != dataBind && (parentMode != DataBindMode::oneWayToSource) && + auto parentFlags = static_cast(dataBindParent->flags()); + if (dataBindParent != dataBind && + (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToTarget) || + ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) && dataBindParent->target() == dataBind->target() && dataBindParent->propertyKey() == dataBind->propertyKey()) { @@ -1071,23 +1074,23 @@ void Artboard::buildDataBindDependencies(std::vector* dataBinds) else { // If the data bind reads from a source we want to add it as dependent - // from any other data bind that writes into that source. + // from any other parent data bind that writes into that source. if (dataBind->is()) { for (auto innerComponent : *dataBinds) { - auto dataBindChild = innerComponent->as(); - if (dataBindChild != dataBind) + auto dataBindParent = innerComponent->as(); + if (dataBindParent != dataBind) { - auto childMode = static_cast(dataBind->modeValue()); - if (childMode == DataBindMode::oneWayToSource || - childMode == DataBindMode::twoWay) + auto parentFlags = static_cast(dataBindParent->flags()); + if (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { - if (dataBindChild->is() && - dataBindChild->as()->source() == + if (dataBindParent->is() && + dataBindParent->as()->source() == dataBind->as()->source()) { - dataBind->addDependent(dataBindChild); + dataBindParent->addDependent(dataBind); break; } } diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index d6f3ce9a..adfa2764 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -1,6 +1,6 @@ #include "rive/data_bind/data_bind.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/artboard.hpp" +#include "rive/data_bind_flags.hpp" #include "rive/generated/core_registry.hpp" #include "rive/data_bind/context/context_value.hpp" #include "rive/data_bind/context/context_value_boolean.hpp" @@ -40,8 +40,9 @@ StatusCode DataBind::import(ImportStack& importStack) { return Super::import(imp void DataBind::buildDependencies() { Super::buildDependencies(); - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { m_target->addDependent(this); } @@ -88,8 +89,9 @@ void DataBind::update(ComponentDirt value) { // TODO: @hernan review how dirt and mode work together. If dirt is not set for // certain modes, we might be able to skip the mode validation. - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToTarget) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { m_ContextValue->apply(m_target, propertyKey()); } @@ -100,8 +102,9 @@ void DataBind::update(ComponentDirt value) void DataBind::updateSourceBinding() { - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { if (m_ContextValue != nullptr) { diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp index a2492265..4bb86f61 100644 --- a/src/data_bind/data_bind_context.cpp +++ b/src/data_bind/data_bind_context.cpp @@ -1,5 +1,5 @@ +#include "rive/data_bind_flags.hpp" #include "rive/data_bind/data_bind_context.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/data_bind/context/context_value_number.hpp" #include "rive/data_bind/context/context_value_string.hpp" #include "rive/data_bind/context/context_value_enum.hpp" @@ -39,41 +39,4 @@ void DataBindContext::bind() Super::bind(); } } -} - -void DataBindContext::update(ComponentDirt value) -{ - if (m_Source != nullptr && m_ContextValue != nullptr) - { - - // Use the ComponentDirt::Components flag to indicate the viewmodel has added or removed - // an element to a list. - if ((value & ComponentDirt::Components) == ComponentDirt::Components) - { - m_ContextValue->update(m_target); - } - if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings) - { - // TODO: @hernan review how dirt and mode work together. If dirt is not set for - // certain modes, we might be able to skip the mode validation. - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) - { - m_ContextValue->apply(m_target, propertyKey()); - } - } - } - Super::update(value); -} - -void DataBindContext::updateSourceBinding() -{ - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) - { - if (m_ContextValue != nullptr) - { - m_ContextValue->applyToSource(m_target, propertyKey()); - } - } } \ No newline at end of file