add arithmetic operation and group converters
two new converters:
- arithmetic operation, that applies a basic arithmetic operation to an input
- group converter: this is a special converter that is used to apply a sequence of converters to a data bound property.
https://github.com/user-attachments/assets/50a0226c-343f-4252-923b-4f0c51ca6c8b
Diffs=
ad34dd4da add arithmetic operation and group converters (#7801)
Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index 7dcbdef..41d3f18 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-f99c93181b2073db07b0c54f766648ce56c89df9
+ad34dd4dae54aa071ca80c457e375c015b9497a8
diff --git a/dev/defs/data_bind/converters/data_converter_group.json b/dev/defs/data_bind/converters/data_converter_group.json
new file mode 100644
index 0000000..acc05f8
--- /dev/null
+++ b/dev/defs/data_bind/converters/data_converter_group.json
@@ -0,0 +1,8 @@
+{
+ "name": "DataConverterGroup",
+ "key": {
+ "int": 499,
+ "string": "dataconvertergroup"
+ },
+ "extends": "data_bind/converters/data_converter.json"
+}
\ No newline at end of file
diff --git a/dev/defs/data_bind/converters/data_converter_group_item.json b/dev/defs/data_bind/converters/data_converter_group_item.json
new file mode 100644
index 0000000..60e95ec
--- /dev/null
+++ b/dev/defs/data_bind/converters/data_converter_group_item.json
@@ -0,0 +1,39 @@
+{
+ "name": "DataConverterGroupItem",
+ "key": {
+ "int": 498,
+ "string": "dataconvertergroupitem"
+ },
+ "properties": {
+ "order": {
+ "type": "FractionalIndex",
+ "initialValue": "FractionalIndex.invalid",
+ "key": {
+ "int": 678,
+ "string": "order"
+ },
+ "runtime": false
+ },
+ "converterId": {
+ "type": "Id",
+ "typeRuntime": "uint",
+ "initialValue": "Core.missingId",
+ "initialValueRuntime": "-1",
+ "key": {
+ "int": 679,
+ "string": "converterid"
+ },
+ "description": "Id of the converter"
+ },
+ "groupId": {
+ "type": "Id",
+ "initialValue": "Core.missingId",
+ "key": {
+ "int": 680,
+ "string": "groupid"
+ },
+ "description": "Id of the group this item belongs to",
+ "runtime": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/dev/defs/data_bind/converters/data_converter_operation.json b/dev/defs/data_bind/converters/data_converter_operation.json
new file mode 100644
index 0000000..1a92179
--- /dev/null
+++ b/dev/defs/data_bind/converters/data_converter_operation.json
@@ -0,0 +1,28 @@
+{
+ "name": "DataConverterOperation",
+ "key": {
+ "int": 500,
+ "string": "dataconverteroperation"
+ },
+ "extends": "data_bind/converters/data_converter.json",
+ "properties": {
+ "value": {
+ "type": "double",
+ "initialValue": "1",
+ "key": {
+ "int": 681,
+ "string": "value"
+ },
+ "description": "Number to multiply the input to"
+ },
+ "operationType": {
+ "type": "uint",
+ "initialValue": "0",
+ "key": {
+ "int": 682,
+ "string": "operationtype"
+ },
+ "description": "The operation tu use for the input and value"
+ }
+ }
+}
\ No newline at end of file
diff --git a/include/rive/animation/arithmetic_operation.hpp b/include/rive/animation/arithmetic_operation.hpp
new file mode 100644
index 0000000..1870b8d
--- /dev/null
+++ b/include/rive/animation/arithmetic_operation.hpp
@@ -0,0 +1,16 @@
+#ifndef _RIVE_ARITHMETIC_OPERATION_HPP_
+#define _RIVE_ARITHMETIC_OPERATION_HPP_
+
+namespace rive
+{
+enum class ArithmeticOperation : int
+{
+ add = 0,
+ subtract = 1,
+ multiply = 2,
+ divide = 3,
+ modulo = 4,
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/data_bind/converters/data_converter_group.hpp b/include/rive/data_bind/converters/data_converter_group.hpp
new file mode 100644
index 0000000..4056085
--- /dev/null
+++ b/include/rive/data_bind/converters/data_converter_group.hpp
@@ -0,0 +1,28 @@
+#ifndef _RIVE_DATA_CONVERTER_GROUP_HPP_
+#define _RIVE_DATA_CONVERTER_GROUP_HPP_
+#include "rive/generated/data_bind/converters/data_converter_group_base.hpp"
+#include "rive/data_bind/converters/data_converter_group_item.hpp"
+#include <stdio.h>
+namespace rive
+{
+class DataConverterGroup : public DataConverterGroupBase
+{
+public:
+ DataValue* convert(DataValue* value) override;
+ DataValue* reverseConvert(DataValue* value) override;
+ void addItem(DataConverterGroupItem* item);
+ DataType outputType() override
+ {
+ if (m_items.size() > 0)
+ {
+ return m_items.back()->converter()->outputType();
+ };
+ return Super::outputType();
+ }
+
+private:
+ std::vector<DataConverterGroupItem*> m_items;
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/data_bind/converters/data_converter_group_item.hpp b/include/rive/data_bind/converters/data_converter_group_item.hpp
new file mode 100644
index 0000000..0a6202d
--- /dev/null
+++ b/include/rive/data_bind/converters/data_converter_group_item.hpp
@@ -0,0 +1,20 @@
+#ifndef _RIVE_DATA_CONVERTER_GROUP_ITEM_HPP_
+#define _RIVE_DATA_CONVERTER_GROUP_ITEM_HPP_
+#include "rive/generated/data_bind/converters/data_converter_group_item_base.hpp"
+#include "rive/data_bind/converters/data_converter.hpp"
+#include <stdio.h>
+namespace rive
+{
+class DataConverterGroupItem : public DataConverterGroupItemBase
+{
+public:
+ StatusCode import(ImportStack& importStack) override;
+ DataConverter* converter() const { return m_dataConverter; };
+ void converter(DataConverter* value) { m_dataConverter = value; };
+
+protected:
+ DataConverter* m_dataConverter;
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/data_bind/converters/data_converter_operation.hpp b/include/rive/data_bind/converters/data_converter_operation.hpp
new file mode 100644
index 0000000..9bbb2b4
--- /dev/null
+++ b/include/rive/data_bind/converters/data_converter_operation.hpp
@@ -0,0 +1,18 @@
+#ifndef _RIVE_DATA_CONVERTER_OPERATION_HPP_
+#define _RIVE_DATA_CONVERTER_OPERATION_HPP_
+#include "rive/generated/data_bind/converters/data_converter_operation_base.hpp"
+#include "rive/animation/arithmetic_operation.hpp"
+#include <stdio.h>
+namespace rive
+{
+class DataConverterOperation : public DataConverterOperationBase
+{
+public:
+ DataValue* convert(DataValue* value) override;
+ DataValue* reverseConvert(DataValue* value) override;
+ DataType outputType() override { return DataType::number; };
+ ArithmeticOperation op() const { return (ArithmeticOperation)operationType(); }
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp
index 77e4251..bb2d399 100644
--- a/include/rive/generated/core_registry.hpp
+++ b/include/rive/generated/core_registry.hpp
@@ -121,6 +121,9 @@
#include "rive/data_bind/bindable_property_number.hpp"
#include "rive/data_bind/bindable_property_string.hpp"
#include "rive/data_bind/converters/data_converter.hpp"
+#include "rive/data_bind/converters/data_converter_group.hpp"
+#include "rive/data_bind/converters/data_converter_group_item.hpp"
+#include "rive/data_bind/converters/data_converter_operation.hpp"
#include "rive/data_bind/converters/data_converter_rounder.hpp"
#include "rive/data_bind/converters/data_converter_to_string.hpp"
#include "rive/data_bind/data_bind.hpp"
@@ -472,8 +475,14 @@
return new BindablePropertyBoolean();
case DataBindBase::typeKey:
return new DataBind();
+ case DataConverterGroupItemBase::typeKey:
+ return new DataConverterGroupItem();
+ case DataConverterGroupBase::typeKey:
+ return new DataConverterGroup();
case DataConverterRounderBase::typeKey:
return new DataConverterRounder();
+ case DataConverterOperationBase::typeKey:
+ return new DataConverterOperation();
case DataConverterToStringBase::typeKey:
return new DataConverterToString();
case DataBindContextBase::typeKey:
@@ -1047,9 +1056,15 @@
case DataBindBase::converterIdPropertyKey:
object->as<DataBindBase>()->converterId(value);
break;
+ case DataConverterGroupItemBase::converterIdPropertyKey:
+ object->as<DataConverterGroupItemBase>()->converterId(value);
+ break;
case DataConverterRounderBase::decimalsPropertyKey:
object->as<DataConverterRounderBase>()->decimals(value);
break;
+ case DataConverterOperationBase::operationTypePropertyKey:
+ object->as<DataConverterOperationBase>()->operationType(value);
+ break;
case BindablePropertyEnumBase::propertyValuePropertyKey:
object->as<BindablePropertyEnumBase>()->propertyValue(value);
break;
@@ -1589,6 +1604,9 @@
case JoystickBase::heightPropertyKey:
object->as<JoystickBase>()->height(value);
break;
+ case DataConverterOperationBase::valuePropertyKey:
+ object->as<DataConverterOperationBase>()->value(value);
+ break;
case BindablePropertyNumberBase::propertyValuePropertyKey:
object->as<BindablePropertyNumberBase>()->propertyValue(value);
break;
@@ -2085,8 +2103,12 @@
return object->as<DataBindBase>()->flags();
case DataBindBase::converterIdPropertyKey:
return object->as<DataBindBase>()->converterId();
+ case DataConverterGroupItemBase::converterIdPropertyKey:
+ return object->as<DataConverterGroupItemBase>()->converterId();
case DataConverterRounderBase::decimalsPropertyKey:
return object->as<DataConverterRounderBase>()->decimals();
+ case DataConverterOperationBase::operationTypePropertyKey:
+ return object->as<DataConverterOperationBase>()->operationType();
case BindablePropertyEnumBase::propertyValuePropertyKey:
return object->as<BindablePropertyEnumBase>()->propertyValue();
case NestedArtboardLeafBase::fitPropertyKey:
@@ -2456,6 +2478,8 @@
return object->as<JoystickBase>()->width();
case JoystickBase::heightPropertyKey:
return object->as<JoystickBase>()->height();
+ case DataConverterOperationBase::valuePropertyKey:
+ return object->as<DataConverterOperationBase>()->value();
case BindablePropertyNumberBase::propertyValuePropertyKey:
return object->as<BindablePropertyNumberBase>()->propertyValue();
case NestedArtboardLeafBase::alignmentXPropertyKey:
@@ -2722,7 +2746,9 @@
case DataBindBase::propertyKeyPropertyKey:
case DataBindBase::flagsPropertyKey:
case DataBindBase::converterIdPropertyKey:
+ case DataConverterGroupItemBase::converterIdPropertyKey:
case DataConverterRounderBase::decimalsPropertyKey:
+ case DataConverterOperationBase::operationTypePropertyKey:
case BindablePropertyEnumBase::propertyValuePropertyKey:
case NestedArtboardLeafBase::fitPropertyKey:
case WeightBase::valuesPropertyKey:
@@ -2901,6 +2927,7 @@
case JoystickBase::originYPropertyKey:
case JoystickBase::widthPropertyKey:
case JoystickBase::heightPropertyKey:
+ case DataConverterOperationBase::valuePropertyKey:
case BindablePropertyNumberBase::propertyValuePropertyKey:
case NestedArtboardLeafBase::alignmentXPropertyKey:
case NestedArtboardLeafBase::alignmentYPropertyKey:
@@ -3308,8 +3335,12 @@
return object->is<DataBindBase>();
case DataBindBase::converterIdPropertyKey:
return object->is<DataBindBase>();
+ case DataConverterGroupItemBase::converterIdPropertyKey:
+ return object->is<DataConverterGroupItemBase>();
case DataConverterRounderBase::decimalsPropertyKey:
return object->is<DataConverterRounderBase>();
+ case DataConverterOperationBase::operationTypePropertyKey:
+ return object->is<DataConverterOperationBase>();
case BindablePropertyEnumBase::propertyValuePropertyKey:
return object->is<BindablePropertyEnumBase>();
case NestedArtboardLeafBase::fitPropertyKey:
@@ -3658,6 +3689,8 @@
return object->is<JoystickBase>();
case JoystickBase::heightPropertyKey:
return object->is<JoystickBase>();
+ case DataConverterOperationBase::valuePropertyKey:
+ return object->is<DataConverterOperationBase>();
case BindablePropertyNumberBase::propertyValuePropertyKey:
return object->is<BindablePropertyNumberBase>();
case NestedArtboardLeafBase::alignmentXPropertyKey:
diff --git a/include/rive/generated/data_bind/converters/data_converter_group_base.hpp b/include/rive/generated/data_bind/converters/data_converter_group_base.hpp
new file mode 100644
index 0000000..32377ba
--- /dev/null
+++ b/include/rive/generated/data_bind/converters/data_converter_group_base.hpp
@@ -0,0 +1,36 @@
+#ifndef _RIVE_DATA_CONVERTER_GROUP_BASE_HPP_
+#define _RIVE_DATA_CONVERTER_GROUP_BASE_HPP_
+#include "rive/data_bind/converters/data_converter.hpp"
+namespace rive
+{
+class DataConverterGroupBase : public DataConverter
+{
+protected:
+ typedef DataConverter Super;
+
+public:
+ static const uint16_t typeKey = 499;
+
+ /// Helper to quickly determine if a core object extends another without RTTI
+ /// at runtime.
+ bool isTypeOf(uint16_t typeKey) const override
+ {
+ switch (typeKey)
+ {
+ case DataConverterGroupBase::typeKey:
+ case DataConverterBase::typeKey:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ uint16_t coreType() const override { return typeKey; }
+
+ Core* clone() const override;
+
+protected:
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp b/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp
new file mode 100644
index 0000000..2f51281
--- /dev/null
+++ b/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp
@@ -0,0 +1,66 @@
+#ifndef _RIVE_DATA_CONVERTER_GROUP_ITEM_BASE_HPP_
+#define _RIVE_DATA_CONVERTER_GROUP_ITEM_BASE_HPP_
+#include "rive/core.hpp"
+#include "rive/core/field_types/core_uint_type.hpp"
+namespace rive
+{
+class DataConverterGroupItemBase : public Core
+{
+protected:
+ typedef Core Super;
+
+public:
+ static const uint16_t typeKey = 498;
+
+ /// Helper to quickly determine if a core object extends another without RTTI
+ /// at runtime.
+ bool isTypeOf(uint16_t typeKey) const override
+ {
+ switch (typeKey)
+ {
+ case DataConverterGroupItemBase::typeKey:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ uint16_t coreType() const override { return typeKey; }
+
+ static const uint16_t converterIdPropertyKey = 679;
+
+private:
+ uint32_t m_ConverterId = -1;
+
+public:
+ inline uint32_t converterId() const { return m_ConverterId; }
+ void converterId(uint32_t value)
+ {
+ if (m_ConverterId == value)
+ {
+ return;
+ }
+ m_ConverterId = value;
+ converterIdChanged();
+ }
+
+ Core* clone() const override;
+ void copy(const DataConverterGroupItemBase& object) { m_ConverterId = object.m_ConverterId; }
+
+ bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
+ {
+ switch (propertyKey)
+ {
+ case converterIdPropertyKey:
+ m_ConverterId = CoreUintType::deserialize(reader);
+ return true;
+ }
+ return false;
+ }
+
+protected:
+ virtual void converterIdChanged() {}
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp b/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp
new file mode 100644
index 0000000..1291318
--- /dev/null
+++ b/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp
@@ -0,0 +1,90 @@
+#ifndef _RIVE_DATA_CONVERTER_OPERATION_BASE_HPP_
+#define _RIVE_DATA_CONVERTER_OPERATION_BASE_HPP_
+#include "rive/core/field_types/core_double_type.hpp"
+#include "rive/core/field_types/core_uint_type.hpp"
+#include "rive/data_bind/converters/data_converter.hpp"
+namespace rive
+{
+class DataConverterOperationBase : public DataConverter
+{
+protected:
+ typedef DataConverter Super;
+
+public:
+ static const uint16_t typeKey = 500;
+
+ /// Helper to quickly determine if a core object extends another without RTTI
+ /// at runtime.
+ bool isTypeOf(uint16_t typeKey) const override
+ {
+ switch (typeKey)
+ {
+ case DataConverterOperationBase::typeKey:
+ case DataConverterBase::typeKey:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ uint16_t coreType() const override { return typeKey; }
+
+ static const uint16_t valuePropertyKey = 681;
+ static const uint16_t operationTypePropertyKey = 682;
+
+private:
+ float m_Value = 1.0f;
+ uint32_t m_OperationType = 0;
+
+public:
+ inline float value() const { return m_Value; }
+ void value(float value)
+ {
+ if (m_Value == value)
+ {
+ return;
+ }
+ m_Value = value;
+ valueChanged();
+ }
+
+ inline uint32_t operationType() const { return m_OperationType; }
+ void operationType(uint32_t value)
+ {
+ if (m_OperationType == value)
+ {
+ return;
+ }
+ m_OperationType = value;
+ operationTypeChanged();
+ }
+
+ Core* clone() const override;
+ void copy(const DataConverterOperationBase& object)
+ {
+ m_Value = object.m_Value;
+ m_OperationType = object.m_OperationType;
+ DataConverter::copy(object);
+ }
+
+ bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
+ {
+ switch (propertyKey)
+ {
+ case valuePropertyKey:
+ m_Value = CoreDoubleType::deserialize(reader);
+ return true;
+ case operationTypePropertyKey:
+ m_OperationType = CoreUintType::deserialize(reader);
+ return true;
+ }
+ return DataConverter::deserialize(propertyKey, reader);
+ }
+
+protected:
+ virtual void valueChanged() {}
+ virtual void operationTypeChanged() {}
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/importers/backboard_importer.hpp b/include/rive/importers/backboard_importer.hpp
index c92454f..cb2f971 100644
--- a/include/rive/importers/backboard_importer.hpp
+++ b/include/rive/importers/backboard_importer.hpp
@@ -14,6 +14,7 @@
class FileAssetReferencer;
class DataConverter;
class DataBind;
+class DataConverterGroupItem;
class BackboardImporter : public ImportStackObject
{
private:
@@ -24,6 +25,7 @@
std::vector<FileAssetReferencer*> m_FileAssetReferencers;
std::vector<DataConverter*> m_DataConverters;
std::vector<DataBind*> m_DataConverterReferencers;
+ std::vector<DataConverterGroupItem*> m_DataConverterGroupItemReferencers;
int m_NextArtboardId;
public:
@@ -35,6 +37,7 @@
void addFileAssetReferencer(FileAssetReferencer* referencer);
void addDataConverterReferencer(DataBind* referencer);
void addDataConverter(DataConverter* converter);
+ void addDataConverterGroupItemReferencer(DataConverterGroupItem* referencer);
StatusCode resolve() override;
const Backboard* backboard() const { return m_Backboard; }
diff --git a/include/rive/importers/data_converter_group_importer.hpp b/include/rive/importers/data_converter_group_importer.hpp
new file mode 100644
index 0000000..61ba8ab
--- /dev/null
+++ b/include/rive/importers/data_converter_group_importer.hpp
@@ -0,0 +1,20 @@
+#ifndef _RIVE_DATA_CONVERTER_GROUP_IMPORTER_HPP_
+#define _RIVE_DATA_CONVERTER_GROUP_IMPORTER_HPP_
+
+#include "rive/importers/import_stack.hpp"
+
+namespace rive
+{
+class Core;
+class DataConverterGroup;
+class DataConverterGroupImporter : public ImportStackObject
+{
+private:
+ DataConverterGroup* m_dataConverterGroup;
+
+public:
+ DataConverterGroupImporter(DataConverterGroup* group);
+ DataConverterGroup* group() { return m_dataConverterGroup; }
+};
+} // namespace rive
+#endif
\ No newline at end of file
diff --git a/src/data_bind/converters/data_converter_group.cpp b/src/data_bind/converters/data_converter_group.cpp
new file mode 100644
index 0000000..aab150f
--- /dev/null
+++ b/src/data_bind/converters/data_converter_group.cpp
@@ -0,0 +1,28 @@
+#include "rive/math/math_types.hpp"
+#include "rive/data_bind/converters/data_converter_group.hpp"
+#include "rive/data_bind/data_values/data_value_number.hpp"
+#include "rive/data_bind/data_values/data_value_string.hpp"
+
+using namespace rive;
+
+void DataConverterGroup::addItem(DataConverterGroupItem* item) { m_items.push_back(item); }
+
+DataValue* DataConverterGroup::convert(DataValue* input)
+{
+ DataValue* value = input;
+ for (auto item : m_items)
+ {
+ value = item->converter()->convert(value);
+ }
+ return value;
+}
+
+DataValue* DataConverterGroup::reverseConvert(DataValue* input)
+{
+ DataValue* value = input;
+ for (auto it = m_items.rbegin(); it != m_items.rend(); ++it)
+ {
+ value = (*it)->converter()->reverseConvert(value);
+ }
+ return value;
+}
\ No newline at end of file
diff --git a/src/data_bind/converters/data_converter_group_item.cpp b/src/data_bind/converters/data_converter_group_item.cpp
new file mode 100644
index 0000000..3a6fa65
--- /dev/null
+++ b/src/data_bind/converters/data_converter_group_item.cpp
@@ -0,0 +1,26 @@
+#include "rive/backboard.hpp"
+#include "rive/math/math_types.hpp"
+#include "rive/data_bind/converters/data_converter_group_item.hpp"
+#include "rive/data_bind/converters/data_converter_group.hpp"
+#include "rive/importers/data_converter_group_importer.hpp"
+#include "rive/importers/backboard_importer.hpp"
+
+using namespace rive;
+
+StatusCode DataConverterGroupItem::import(ImportStack& importStack)
+{
+ auto backboardImporter = importStack.latest<BackboardImporter>(Backboard::typeKey);
+ if (backboardImporter == nullptr)
+ {
+ return StatusCode::MissingObject;
+ }
+ backboardImporter->addDataConverterGroupItemReferencer(this);
+ auto dataConveterGroupImporter =
+ importStack.latest<DataConverterGroupImporter>(DataConverterGroupBase::typeKey);
+ if (dataConveterGroupImporter == nullptr)
+ {
+ return StatusCode::MissingObject;
+ }
+ dataConveterGroupImporter->group()->addItem(this);
+ return Super::import(importStack);
+}
\ No newline at end of file
diff --git a/src/data_bind/converters/data_converter_operation.cpp b/src/data_bind/converters/data_converter_operation.cpp
new file mode 100644
index 0000000..dfb43d8
--- /dev/null
+++ b/src/data_bind/converters/data_converter_operation.cpp
@@ -0,0 +1,65 @@
+#include "rive/math/math_types.hpp"
+#include "rive/data_bind/converters/data_converter_operation.hpp"
+#include "rive/data_bind/data_values/data_value_number.hpp"
+
+using namespace rive;
+
+DataValue* DataConverterOperation::convert(DataValue* input)
+{
+ auto output = new DataValueNumber();
+ if (input->is<DataValueNumber>())
+ {
+ float inputValue = input->as<DataValueNumber>()->value();
+ float resultValue = value();
+ switch (op())
+ {
+ case ArithmeticOperation::add:
+ resultValue = inputValue + resultValue;
+ break;
+ case ArithmeticOperation::subtract:
+ resultValue = inputValue - resultValue;
+ break;
+ case ArithmeticOperation::multiply:
+ resultValue = inputValue * resultValue;
+ break;
+ case ArithmeticOperation::divide:
+ resultValue = inputValue / resultValue;
+ break;
+ case ArithmeticOperation::modulo:
+ resultValue = fmodf(inputValue, resultValue);
+ break;
+ }
+ output->value(resultValue);
+ }
+ return output;
+}
+
+DataValue* DataConverterOperation::reverseConvert(DataValue* input)
+{
+ auto output = new DataValueNumber();
+ if (input->is<DataValueNumber>())
+ {
+ float inputValue = input->as<DataValueNumber>()->value();
+ float resultValue = value();
+ switch (op())
+ {
+ case ArithmeticOperation::add:
+ resultValue = inputValue - resultValue;
+ break;
+ case ArithmeticOperation::subtract:
+ resultValue = inputValue + resultValue;
+ break;
+ case ArithmeticOperation::multiply:
+ resultValue = inputValue / resultValue;
+ break;
+ case ArithmeticOperation::divide:
+ resultValue = inputValue * resultValue;
+ break;
+ // No reverse operation for modulo
+ case ArithmeticOperation::modulo:
+ break;
+ }
+ output->value(resultValue);
+ }
+ return output;
+}
\ No newline at end of file
diff --git a/src/file.cpp b/src/file.cpp
index 100969e..db3e98f 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -9,6 +9,7 @@
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/importers/bindable_property_importer.hpp"
+#include "rive/importers/data_converter_group_importer.hpp"
#include "rive/importers/enum_importer.hpp"
#include "rive/importers/file_asset_importer.hpp"
#include "rive/importers/import_stack.hpp"
@@ -39,6 +40,7 @@
#include "rive/data_bind/bindable_property_color.hpp"
#include "rive/data_bind/bindable_property_enum.hpp"
#include "rive/data_bind/bindable_property_boolean.hpp"
+#include "rive/data_bind/converters/data_converter_group.hpp"
#include "rive/assets/file_asset.hpp"
#include "rive/assets/audio_asset.hpp"
#include "rive/assets/file_asset_contents.hpp"
@@ -389,6 +391,11 @@
rivestd::make_unique<BindablePropertyImporter>(object->as<BindableProperty>());
stackType = BindablePropertyBase::typeKey;
break;
+ case DataConverterGroupBase::typeKey:
+ stackObject = rivestd::make_unique<DataConverterGroupImporter>(
+ object->as<DataConverterGroup>());
+ stackType = DataConverterGroupBase::typeKey;
+ break;
}
if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok)
{
diff --git a/src/generated/data_bind/converters/data_converter_group_base.cpp b/src/generated/data_bind/converters/data_converter_group_base.cpp
new file mode 100644
index 0000000..23ee770
--- /dev/null
+++ b/src/generated/data_bind/converters/data_converter_group_base.cpp
@@ -0,0 +1,11 @@
+#include "rive/generated/data_bind/converters/data_converter_group_base.hpp"
+#include "rive/data_bind/converters/data_converter_group.hpp"
+
+using namespace rive;
+
+Core* DataConverterGroupBase::clone() const
+{
+ auto cloned = new DataConverterGroup();
+ cloned->copy(*this);
+ return cloned;
+}
diff --git a/src/generated/data_bind/converters/data_converter_group_item_base.cpp b/src/generated/data_bind/converters/data_converter_group_item_base.cpp
new file mode 100644
index 0000000..8f1e17b
--- /dev/null
+++ b/src/generated/data_bind/converters/data_converter_group_item_base.cpp
@@ -0,0 +1,11 @@
+#include "rive/generated/data_bind/converters/data_converter_group_item_base.hpp"
+#include "rive/data_bind/converters/data_converter_group_item.hpp"
+
+using namespace rive;
+
+Core* DataConverterGroupItemBase::clone() const
+{
+ auto cloned = new DataConverterGroupItem();
+ cloned->copy(*this);
+ return cloned;
+}
diff --git a/src/generated/data_bind/converters/data_converter_operation_base.cpp b/src/generated/data_bind/converters/data_converter_operation_base.cpp
new file mode 100644
index 0000000..77ee84b
--- /dev/null
+++ b/src/generated/data_bind/converters/data_converter_operation_base.cpp
@@ -0,0 +1,11 @@
+#include "rive/generated/data_bind/converters/data_converter_operation_base.hpp"
+#include "rive/data_bind/converters/data_converter_operation.hpp"
+
+using namespace rive;
+
+Core* DataConverterOperationBase::clone() const
+{
+ auto cloned = new DataConverterOperation();
+ cloned->copy(*this);
+ return cloned;
+}
diff --git a/src/importers/backboard_importer.cpp b/src/importers/backboard_importer.cpp
index 845c536..97a6c55 100644
--- a/src/importers/backboard_importer.cpp
+++ b/src/importers/backboard_importer.cpp
@@ -8,6 +8,7 @@
#include "rive/viewmodel/viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/data_bind/converters/data_converter.hpp"
+#include "rive/data_bind/converters/data_converter_group_item.hpp"
#include "rive/data_bind/data_bind.hpp"
#include <unordered_set>
@@ -96,7 +97,15 @@
}
referencer->converter(m_DataConverters[index]);
}
-
+ for (auto referencer : m_DataConverterGroupItemReferencers)
+ {
+ auto index = (size_t)referencer->converterId();
+ if (index >= m_DataConverters.size() || index < 0)
+ {
+ continue;
+ }
+ referencer->converter(m_DataConverters[index]);
+ }
return StatusCode::Ok;
}
@@ -108,4 +117,9 @@
void BackboardImporter::addDataConverterReferencer(DataBind* dataBind)
{
m_DataConverterReferencers.push_back(dataBind);
+}
+
+void BackboardImporter::addDataConverterGroupItemReferencer(DataConverterGroupItem* dataBind)
+{
+ m_DataConverterGroupItemReferencers.push_back(dataBind);
}
\ No newline at end of file
diff --git a/src/importers/data_converter_group_importer.cpp b/src/importers/data_converter_group_importer.cpp
new file mode 100644
index 0000000..457a0e2
--- /dev/null
+++ b/src/importers/data_converter_group_importer.cpp
@@ -0,0 +1,9 @@
+#include "rive/artboard.hpp"
+#include "rive/importers/data_converter_group_importer.hpp"
+#include "rive/data_bind/converters/data_converter.hpp"
+
+using namespace rive;
+
+DataConverterGroupImporter::DataConverterGroupImporter(DataConverterGroup* group) :
+ m_dataConverterGroup(group)
+{}
\ No newline at end of file