Skip to content

Commit

Permalink
update data bind mode to flags
Browse files Browse the repository at this point in the history
change how we store data bind mode.
This will be helpful once we implement converters to identify whether a converter's main direction is "toSource" or "toTarget".
It also cleans up how the modal works and saves changes in real time instead of doing it on "Save"

<img width="606" alt="data_bind_mode" src="https://github.com/user-attachments/assets/3662df84-e05a-4ea0-aaea-37e0b1294da0">

Diffs=
49cabe3cb update data bind mode to flags (#7612)

Co-authored-by: hernan <[email protected]>
  • Loading branch information
bodymovin and bodymovin committed Jul 17, 2024
1 parent 88375e7 commit 332db4c
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6c5c79b751c50fa4393fb0e44624635861bc3f3b
49cabe3cbd9c9683bd704e0d72a455d698bfe061
8 changes: 3 additions & 5 deletions dev/defs/data_bind/data_bind.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
}
2 changes: 0 additions & 2 deletions include/rive/data_bind/data_bind_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ class DataBindContext : public DataBindContextBase
std::vector<uint32_t> m_SourcePathIdsBuffer;

public:
void update(ComponentDirt value) override;
void decodeSourcePathIds(Span<const uint8_t> value) override;
void copySourcePathIds(const DataBindContextBase& object) override;
void bind() override;
void updateSourceBinding() override;
ViewModelInstanceValue* source() { return m_Source; };
};
} // namespace rive
Expand Down
13 changes: 0 additions & 13 deletions include/rive/data_bind/data_bind_mode.hpp

This file was deleted.

29 changes: 29 additions & 0 deletions include/rive/data_bind_flags.hpp
Original file line number Diff line number Diff line change
@@ -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
12 changes: 6 additions & 6 deletions include/rive/generated/core_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,8 @@ class CoreRegistry
case DataBindBase::propertyKeyPropertyKey:
object->as<DataBindBase>()->propertyKey(value);
break;
case DataBindBase::modeValuePropertyKey:
object->as<DataBindBase>()->modeValue(value);
case DataBindBase::flagsPropertyKey:
object->as<DataBindBase>()->flags(value);
break;
case WeightBase::valuesPropertyKey:
object->as<WeightBase>()->values(value);
Expand Down Expand Up @@ -1884,8 +1884,8 @@ class CoreRegistry
return object->as<DataBindBase>()->targetId();
case DataBindBase::propertyKeyPropertyKey:
return object->as<DataBindBase>()->propertyKey();
case DataBindBase::modeValuePropertyKey:
return object->as<DataBindBase>()->modeValue();
case DataBindBase::flagsPropertyKey:
return object->as<DataBindBase>()->flags();
case WeightBase::valuesPropertyKey:
return object->as<WeightBase>()->values();
case WeightBase::indicesPropertyKey:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -3010,7 +3010,7 @@ class CoreRegistry
return object->is<DataBindBase>();
case DataBindBase::propertyKeyPropertyKey:
return object->is<DataBindBase>();
case DataBindBase::modeValuePropertyKey:
case DataBindBase::flagsPropertyKey:
return object->is<DataBindBase>();
case WeightBase::valuesPropertyKey:
return object->is<WeightBase>();
Expand Down
22 changes: 11 additions & 11 deletions include/rive/generated/data_bind/data_bind_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -60,23 +60,23 @@ 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;
void copy(const DataBindBase& object)
{
m_TargetId = object.m_TargetId;
m_PropertyKey = object.m_PropertyKey;
m_ModeValue = object.m_ModeValue;
m_Flags = object.m_Flags;
Component::copy(object);
}

Expand All @@ -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);
Expand All @@ -100,7 +100,7 @@ class DataBindBase : public Component
protected:
virtual void targetIdChanged() {}
virtual void propertyKeyChanged() {}
virtual void modeValueChanged() {}
virtual void flagsChanged() {}
};
} // namespace rive

Expand Down
33 changes: 18 additions & 15 deletions src/artboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -1050,16 +1050,19 @@ void Artboard::buildDataBindDependencies(std::vector<Component*>* dataBinds)
for (auto component : *dataBinds)
{
auto dataBind = component->as<DataBind>();
auto mode = static_cast<DataBindMode>(dataBind->modeValue());
auto flags = static_cast<DataBindFlags>(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<DataBind>();
auto parentMode = static_cast<DataBindMode>(dataBind->modeValue());
if (dataBindParent != dataBind && (parentMode != DataBindMode::oneWayToSource) &&
auto parentFlags = static_cast<DataBindFlags>(dataBindParent->flags());
if (dataBindParent != dataBind &&
(((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToTarget) ||
((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) &&
dataBindParent->target() == dataBind->target() &&
dataBindParent->propertyKey() == dataBind->propertyKey())
{
Expand All @@ -1071,23 +1074,23 @@ void Artboard::buildDataBindDependencies(std::vector<Component*>* 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<DataBindContext>())
{
for (auto innerComponent : *dataBinds)
{
auto dataBindChild = innerComponent->as<DataBind>();
if (dataBindChild != dataBind)
auto dataBindParent = innerComponent->as<DataBind>();
if (dataBindParent != dataBind)
{
auto childMode = static_cast<DataBindMode>(dataBind->modeValue());
if (childMode == DataBindMode::oneWayToSource ||
childMode == DataBindMode::twoWay)
auto parentFlags = static_cast<DataBindFlags>(dataBindParent->flags());
if (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
{
if (dataBindChild->is<DataBindContext>() &&
dataBindChild->as<DataBindContext>()->source() ==
if (dataBindParent->is<DataBindContext>() &&
dataBindParent->as<DataBindContext>()->source() ==
dataBind->as<DataBindContext>()->source())
{
dataBind->addDependent(dataBindChild);
dataBindParent->addDependent(dataBind);
break;
}
}
Expand Down
17 changes: 10 additions & 7 deletions src/data_bind/data_bind.cpp
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -40,8 +40,9 @@ StatusCode DataBind::import(ImportStack& importStack) { return Super::import(imp
void DataBind::buildDependencies()
{
Super::buildDependencies();
auto mode = static_cast<DataBindMode>(modeValue());
if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
auto flagsValue = static_cast<DataBindFlags>(flags());
if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
{
m_target->addDependent(this);
}
Expand Down Expand Up @@ -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<DataBindMode>(modeValue());
if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay)
auto flagsValue = static_cast<DataBindFlags>(flags());
if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToTarget) ||
((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
{
m_ContextValue->apply(m_target, propertyKey());
}
Expand All @@ -100,8 +102,9 @@ void DataBind::update(ComponentDirt value)

void DataBind::updateSourceBinding()
{
auto mode = static_cast<DataBindMode>(modeValue());
if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
auto flagsValue = static_cast<DataBindFlags>(flags());
if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
{
if (m_ContextValue != nullptr)
{
Expand Down
39 changes: 1 addition & 38 deletions src/data_bind/data_bind_context.cpp
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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<DataBindMode>(modeValue());
if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay)
{
m_ContextValue->apply(m_target, propertyKey());
}
}
}
Super::update(value);
}

void DataBindContext::updateSourceBinding()
{
auto mode = static_cast<DataBindMode>(modeValue());
if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
{
if (m_ContextValue != nullptr)
{
m_ContextValue->applyToSource(m_target, propertyKey());
}
}
}

0 comments on commit 332db4c

Please sign in to comment.