Use artboard properties as transition conditions

Adding support for transition conditions based on artboard properties.
transition_artboard_condition extends from transition_viewmodel_condition.
It might be good to rename  transition_viewmodel_condition to transition_property_condition at some point since it is extensible enough to support viewmodels, but also with other properties like here.

Diffs=
93cc33b45 Use artboard properties as transition conditions (#7796)

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index f62275e..7e901c4 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-c5fc07de9cc2d14a2d223397c8ea96d7393eb78e
+93cc33b45086e528b22d1245a8f7855bac299a21
diff --git a/dev/defs/animation/transition_artboard_condition.json b/dev/defs/animation/transition_artboard_condition.json
new file mode 100644
index 0000000..5a39c66
--- /dev/null
+++ b/dev/defs/animation/transition_artboard_condition.json
@@ -0,0 +1,8 @@
+{
+  "name": "TransitionArtboardCondition",
+  "key": {
+    "int": 497,
+    "string": "transitionartboardcondition"
+  },
+  "extends": "animation/transition_viewmodel_condition.json"
+}
\ No newline at end of file
diff --git a/dev/defs/animation/transition_property_artboard_comparator.json b/dev/defs/animation/transition_property_artboard_comparator.json
new file mode 100644
index 0000000..a9502eb
--- /dev/null
+++ b/dev/defs/animation/transition_property_artboard_comparator.json
@@ -0,0 +1,19 @@
+{
+  "name": "TransitionPropertyArtboardComparator",
+  "key": {
+    "int": 496,
+    "string": "transitionpropertyartboardcomparator"
+  },
+  "extends": "animation/transition_property_comparator.json",
+  "properties": {
+    "propertyType": {
+      "type": "uint",
+      "initialValue": "0",
+      "key": {
+        "int": 677,
+        "string": "propertytype"
+      },
+      "description": "Integer representation of the artboard's property used for condition"
+    }
+  }
+}
\ No newline at end of file
diff --git a/include/rive/animation/artboard_property.hpp b/include/rive/animation/artboard_property.hpp
new file mode 100644
index 0000000..0a4d606
--- /dev/null
+++ b/include/rive/animation/artboard_property.hpp
@@ -0,0 +1,14 @@
+#ifndef _RIVE_ARTBOARD_PROPERTY_HPP_
+#define _RIVE_ARTBOARD_PROPERTY_HPP_
+
+namespace rive
+{
+enum class ArtboardProperty : int
+{
+    width = 0,
+    height = 1,
+    ratio = 2,
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_artboard_condition.hpp b/include/rive/animation/transition_artboard_condition.hpp
new file mode 100644
index 0000000..7892537
--- /dev/null
+++ b/include/rive/animation/transition_artboard_condition.hpp
@@ -0,0 +1,13 @@
+#ifndef _RIVE_TRANSITION_ARTBOARD_CONDITION_HPP_
+#define _RIVE_TRANSITION_ARTBOARD_CONDITION_HPP_
+#include "rive/generated/animation/transition_artboard_condition_base.hpp"
+#include <stdio.h>
+namespace rive
+{
+class TransitionArtboardCondition : public TransitionArtboardConditionBase
+{
+public:
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_property_artboard_comparator.hpp b/include/rive/animation/transition_property_artboard_comparator.hpp
new file mode 100644
index 0000000..184b649
--- /dev/null
+++ b/include/rive/animation/transition_property_artboard_comparator.hpp
@@ -0,0 +1,20 @@
+#ifndef _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_HPP_
+#define _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_HPP_
+#include "rive/generated/animation/transition_property_artboard_comparator_base.hpp"
+#include <stdio.h>
+namespace rive
+{
+class Artboard;
+class TransitionPropertyArtboardComparator : public TransitionPropertyArtboardComparatorBase
+{
+public:
+    bool compare(TransitionComparator* comparand,
+                 TransitionConditionOp operation,
+                 const StateMachineInstance* stateMachineInstance) override;
+
+private:
+    float propertyValue(const StateMachineInstance* stateMachineInstance);
+};
+} // namespace rive
+
+#endif
\ No newline at end of file
diff --git a/include/rive/generated/animation/transition_artboard_condition_base.hpp b/include/rive/generated/animation/transition_artboard_condition_base.hpp
new file mode 100644
index 0000000..5f079c4
--- /dev/null
+++ b/include/rive/generated/animation/transition_artboard_condition_base.hpp
@@ -0,0 +1,37 @@
+#ifndef _RIVE_TRANSITION_ARTBOARD_CONDITION_BASE_HPP_
+#define _RIVE_TRANSITION_ARTBOARD_CONDITION_BASE_HPP_
+#include "rive/animation/transition_viewmodel_condition.hpp"
+namespace rive
+{
+class TransitionArtboardConditionBase : public TransitionViewModelCondition
+{
+protected:
+    typedef TransitionViewModelCondition Super;
+
+public:
+    static const uint16_t typeKey = 497;
+
+    /// Helper to quickly determine if a core object extends another without RTTI
+    /// at runtime.
+    bool isTypeOf(uint16_t typeKey) const override
+    {
+        switch (typeKey)
+        {
+            case TransitionArtboardConditionBase::typeKey:
+            case TransitionViewModelConditionBase::typeKey:
+            case TransitionConditionBase::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/animation/transition_property_artboard_comparator_base.hpp b/include/rive/generated/animation/transition_property_artboard_comparator_base.hpp
new file mode 100644
index 0000000..354087a
--- /dev/null
+++ b/include/rive/generated/animation/transition_property_artboard_comparator_base.hpp
@@ -0,0 +1,72 @@
+#ifndef _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_BASE_HPP_
+#define _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_BASE_HPP_
+#include "rive/animation/transition_property_comparator.hpp"
+#include "rive/core/field_types/core_uint_type.hpp"
+namespace rive
+{
+class TransitionPropertyArtboardComparatorBase : public TransitionPropertyComparator
+{
+protected:
+    typedef TransitionPropertyComparator Super;
+
+public:
+    static const uint16_t typeKey = 496;
+
+    /// Helper to quickly determine if a core object extends another without RTTI
+    /// at runtime.
+    bool isTypeOf(uint16_t typeKey) const override
+    {
+        switch (typeKey)
+        {
+            case TransitionPropertyArtboardComparatorBase::typeKey:
+            case TransitionPropertyComparatorBase::typeKey:
+            case TransitionComparatorBase::typeKey:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    uint16_t coreType() const override { return typeKey; }
+
+    static const uint16_t propertyTypePropertyKey = 677;
+
+private:
+    uint32_t m_PropertyType = 0;
+
+public:
+    inline uint32_t propertyType() const { return m_PropertyType; }
+    void propertyType(uint32_t value)
+    {
+        if (m_PropertyType == value)
+        {
+            return;
+        }
+        m_PropertyType = value;
+        propertyTypeChanged();
+    }
+
+    Core* clone() const override;
+    void copy(const TransitionPropertyArtboardComparatorBase& object)
+    {
+        m_PropertyType = object.m_PropertyType;
+        TransitionPropertyComparator::copy(object);
+    }
+
+    bool deserialize(uint16_t propertyKey, BinaryReader& reader) override
+    {
+        switch (propertyKey)
+        {
+            case propertyTypePropertyKey:
+                m_PropertyType = CoreUintType::deserialize(reader);
+                return true;
+        }
+        return TransitionPropertyComparator::deserialize(propertyKey, reader);
+    }
+
+protected:
+    virtual void propertyTypeChanged() {}
+};
+} // 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 fd25b4c..77e4251 100644
--- a/include/rive/generated/core_registry.hpp
+++ b/include/rive/generated/core_registry.hpp
@@ -59,11 +59,13 @@
 #include "rive/animation/state_machine_number.hpp"
 #include "rive/animation/state_machine_trigger.hpp"
 #include "rive/animation/state_transition.hpp"
+#include "rive/animation/transition_artboard_condition.hpp"
 #include "rive/animation/transition_bool_condition.hpp"
 #include "rive/animation/transition_comparator.hpp"
 #include "rive/animation/transition_condition.hpp"
 #include "rive/animation/transition_input_condition.hpp"
 #include "rive/animation/transition_number_condition.hpp"
+#include "rive/animation/transition_property_artboard_comparator.hpp"
 #include "rive/animation/transition_property_comparator.hpp"
 #include "rive/animation/transition_property_viewmodel_comparator.hpp"
 #include "rive/animation/transition_trigger_condition.hpp"
@@ -318,6 +320,8 @@
                 return new KeyedProperty();
             case StateMachineListenerBase::typeKey:
                 return new StateMachineListener();
+            case TransitionPropertyArtboardComparatorBase::typeKey:
+                return new TransitionPropertyArtboardComparator();
             case TransitionPropertyViewModelComparatorBase::typeKey:
                 return new TransitionPropertyViewModelComparator();
             case KeyFrameIdBase::typeKey:
@@ -332,6 +336,10 @@
                 return new TransitionNumberCondition();
             case TransitionValueBooleanComparatorBase::typeKey:
                 return new TransitionValueBooleanComparator();
+            case TransitionViewModelConditionBase::typeKey:
+                return new TransitionViewModelCondition();
+            case TransitionArtboardConditionBase::typeKey:
+                return new TransitionArtboardCondition();
             case AnyStateBase::typeKey:
                 return new AnyState();
             case CubicInterpolatorComponentBase::typeKey:
@@ -342,8 +350,6 @@
                 return new KeyFrameString();
             case ListenerNumberChangeBase::typeKey:
                 return new ListenerNumberChange();
-            case TransitionViewModelConditionBase::typeKey:
-                return new TransitionViewModelCondition();
             case CubicEaseInterpolatorBase::typeKey:
                 return new CubicEaseInterpolator();
             case StateTransitionBase::typeKey:
@@ -900,6 +906,9 @@
             case StateMachineListenerBase::eventIdPropertyKey:
                 object->as<StateMachineListenerBase>()->eventId(value);
                 break;
+            case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey:
+                object->as<TransitionPropertyArtboardComparatorBase>()->propertyType(value);
+                break;
             case KeyFrameIdBase::valuePropertyKey:
                 object->as<KeyFrameIdBase>()->value(value);
                 break;
@@ -1982,6 +1991,8 @@
                 return object->as<StateMachineListenerBase>()->listenerTypeValue();
             case StateMachineListenerBase::eventIdPropertyKey:
                 return object->as<StateMachineListenerBase>()->eventId();
+            case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey:
+                return object->as<TransitionPropertyArtboardComparatorBase>()->propertyType();
             case KeyFrameIdBase::valuePropertyKey:
                 return object->as<KeyFrameIdBase>()->value();
             case ListenerBoolChangeBase::valuePropertyKey:
@@ -2664,6 +2675,7 @@
             case StateMachineListenerBase::targetIdPropertyKey:
             case StateMachineListenerBase::listenerTypeValuePropertyKey:
             case StateMachineListenerBase::eventIdPropertyKey:
+            case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey:
             case KeyFrameIdBase::valuePropertyKey:
             case ListenerBoolChangeBase::valuePropertyKey:
             case ListenerAlignTargetBase::targetIdPropertyKey:
@@ -3202,6 +3214,8 @@
                 return object->is<StateMachineListenerBase>();
             case StateMachineListenerBase::eventIdPropertyKey:
                 return object->is<StateMachineListenerBase>();
+            case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey:
+                return object->is<TransitionPropertyArtboardComparatorBase>();
             case KeyFrameIdBase::valuePropertyKey:
                 return object->is<KeyFrameIdBase>();
             case ListenerBoolChangeBase::valuePropertyKey:
diff --git a/src/animation/transition_property_artboard_comparator.cpp b/src/animation/transition_property_artboard_comparator.cpp
new file mode 100644
index 0000000..a769c7e
--- /dev/null
+++ b/src/animation/transition_property_artboard_comparator.cpp
@@ -0,0 +1,54 @@
+#include "rive/animation/transition_property_artboard_comparator.hpp"
+#include "rive/animation/transition_property_viewmodel_comparator.hpp"
+#include "rive/animation/transition_value_number_comparator.hpp"
+#include "rive/animation/artboard_property.hpp"
+#include "rive/animation/state_machine_instance.hpp"
+#include "rive/data_bind/bindable_property_number.hpp"
+
+using namespace rive;
+
+float TransitionPropertyArtboardComparator::propertyValue(
+    const StateMachineInstance* stateMachineInstance)
+{
+    auto artboard = stateMachineInstance->artboard();
+    if (artboard != nullptr)
+    {
+
+        auto property = static_cast<ArtboardProperty>(propertyType());
+        switch (property)
+        {
+            case ArtboardProperty::width:
+                return artboard->layoutWidth();
+                break;
+            case ArtboardProperty::height:
+                return artboard->layoutHeight();
+                break;
+            case ArtboardProperty::ratio:
+                return artboard->layoutWidth() / artboard->layoutHeight();
+                break;
+
+            default:
+                break;
+        }
+    }
+    return 0;
+}
+
+bool TransitionPropertyArtboardComparator::compare(TransitionComparator* comparand,
+                                                   TransitionConditionOp operation,
+                                                   const StateMachineInstance* stateMachineInstance)
+{
+    auto value = propertyValue(stateMachineInstance);
+    if (comparand->is<TransitionPropertyViewModelComparator>())
+    {
+        auto rightValue = comparand->as<TransitionPropertyViewModelComparator>()
+                              ->value<BindablePropertyNumber, float>(stateMachineInstance);
+        return compareNumbers(value, rightValue, operation);
+    }
+    else if (comparand->is<TransitionValueNumberComparator>())
+    {
+        auto rightValue = comparand->as<TransitionValueNumberComparator>()->value();
+        return compareNumbers(value, rightValue, operation);
+    }
+    return false;
+}
\ No newline at end of file
diff --git a/src/file.cpp b/src/file.cpp
index 96da684..100969e 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -375,6 +375,7 @@
                 stackType = ViewModelInstanceList::typeKey;
                 break;
             case TransitionViewModelCondition::typeKey:
+            case TransitionArtboardCondition::typeKey:
                 stackObject = rivestd::make_unique<TransitionViewModelConditionImporter>(
                     object->as<TransitionViewModelCondition>());
                 stackType = TransitionViewModelCondition::typeKey;
diff --git a/src/generated/animation/transition_artboard_condition_base.cpp b/src/generated/animation/transition_artboard_condition_base.cpp
new file mode 100644
index 0000000..4adb3c8
--- /dev/null
+++ b/src/generated/animation/transition_artboard_condition_base.cpp
@@ -0,0 +1,11 @@
+#include "rive/generated/animation/transition_artboard_condition_base.hpp"
+#include "rive/animation/transition_artboard_condition.hpp"
+
+using namespace rive;
+
+Core* TransitionArtboardConditionBase::clone() const
+{
+    auto cloned = new TransitionArtboardCondition();
+    cloned->copy(*this);
+    return cloned;
+}
diff --git a/src/generated/animation/transition_property_artboard_comparator_base.cpp b/src/generated/animation/transition_property_artboard_comparator_base.cpp
new file mode 100644
index 0000000..31a068a
--- /dev/null
+++ b/src/generated/animation/transition_property_artboard_comparator_base.cpp
@@ -0,0 +1,11 @@
+#include "rive/generated/animation/transition_property_artboard_comparator_base.hpp"
+#include "rive/animation/transition_property_artboard_comparator.hpp"
+
+using namespace rive;
+
+Core* TransitionPropertyArtboardComparatorBase::clone() const
+{
+    auto cloned = new TransitionPropertyArtboardComparator();
+    cloned->copy(*this);
+    return cloned;
+}