chore: Preprocess transitions conditions on initialization (#11150) bb52cbd4a3
Preprocess transitions conditions on initialization

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index 7c663e5..56d0ca8 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-0791ee519da721cd018cf3955906563ddc576117
+bb52cbd4a32279bb196cea7d18e853893cccf70e
diff --git a/include/rive/animation/transition_comparator.hpp b/include/rive/animation/transition_comparator.hpp
index 337811a..ff9b7e1 100644
--- a/include/rive/animation/transition_comparator.hpp
+++ b/include/rive/animation/transition_comparator.hpp
@@ -13,49 +13,9 @@
 {
 public:
     StatusCode import(ImportStack& importStack) override;
-    virtual bool compare(TransitionComparator* comparand,
-                         TransitionConditionOp operation,
-                         const StateMachineInstance* stateMachineInstance,
-                         StateMachineLayerInstance* layerInstance);
 
     virtual void useInLayer(const StateMachineInstance* stateMachineInstance,
-                            StateMachineLayerInstance* layerInstance) const
-    {}
-
-protected:
-    bool compareNumbers(float left, float right, TransitionConditionOp op);
-    bool compareBooleans(bool left, bool right, TransitionConditionOp op);
-    bool compareEnums(uint16_t left, uint16_t right, TransitionConditionOp op);
-    bool compareColors(int left, int right, TransitionConditionOp op);
-    bool compareStrings(std::string left,
-                        std::string right,
-                        TransitionConditionOp op);
-    bool compareTriggers(uint32_t left,
-                         uint32_t right,
-                         TransitionConditionOp op);
-    bool compareIds(uint32_t left, uint32_t right, TransitionConditionOp op);
-    template <typename T>
-    bool compareComparables(T left, T right, TransitionConditionOp op)
-    {
-        switch (op)
-        {
-            case TransitionConditionOp::equal:
-                return left == right;
-            case TransitionConditionOp::notEqual:
-                return left != right;
-            case TransitionConditionOp::lessThanOrEqual:
-                return left <= right;
-            case TransitionConditionOp::lessThan:
-                return left < right;
-            case TransitionConditionOp::greaterThanOrEqual:
-                return left >= right;
-            case TransitionConditionOp::greaterThan:
-                return left > right;
-            default:
-                return false;
-        }
-    }
+                            StateMachineLayerInstance* layerInstance) const {};
 };
 } // 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
index 448f498..9efd06e 100644
--- a/include/rive/animation/transition_property_artboard_comparator.hpp
+++ b/include/rive/animation/transition_property_artboard_comparator.hpp
@@ -7,16 +7,7 @@
 class Artboard;
 class TransitionPropertyArtboardComparator
     : public TransitionPropertyArtboardComparatorBase
-{
-public:
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
-
-private:
-    float propertyValue(const StateMachineInstance* stateMachineInstance);
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_property_viewmodel_comparator.hpp b/include/rive/animation/transition_property_viewmodel_comparator.hpp
index 87fe6d1..2df3702 100644
--- a/include/rive/animation/transition_property_viewmodel_comparator.hpp
+++ b/include/rive/animation/transition_property_viewmodel_comparator.hpp
@@ -12,10 +12,6 @@
 public:
     ~TransitionPropertyViewModelComparator();
     StatusCode import(ImportStack& importStack) override;
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
     template <typename T = BindableProperty, typename U>
     U value(const StateMachineInstance* stateMachineInstance)
     {
@@ -31,10 +27,9 @@
         }
         return T::defaultValue;
     };
-    float valueToFloat(const StateMachineInstance* stateMachineInstance);
     void useInLayer(const StateMachineInstance* stateMachineInstance,
                     StateMachineLayerInstance* layerInstance) const override;
-    DataType instanceDataType(const StateMachineInstance* stateMachineInstance);
+    BindableProperty* bindableProperty() { return m_bindableProperty; }
 
 protected:
     BindableProperty* m_bindableProperty;
diff --git a/include/rive/animation/transition_value_artboard_comparator.hpp b/include/rive/animation/transition_value_artboard_comparator.hpp
index 3533ae6..ea3e03a 100644
--- a/include/rive/animation/transition_value_artboard_comparator.hpp
+++ b/include/rive/animation/transition_value_artboard_comparator.hpp
@@ -6,9 +6,7 @@
 {
 class TransitionValueArtboardComparator
     : public TransitionValueArtboardComparatorBase
-{
-public:
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_value_boolean_comparator.hpp b/include/rive/animation/transition_value_boolean_comparator.hpp
index 9bc9f5d..1ccaf32 100644
--- a/include/rive/animation/transition_value_boolean_comparator.hpp
+++ b/include/rive/animation/transition_value_boolean_comparator.hpp
@@ -6,13 +6,7 @@
 {
 class TransitionValueBooleanComparator
     : public TransitionValueBooleanComparatorBase
-{
-public:
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_value_color_comparator.hpp b/include/rive/animation/transition_value_color_comparator.hpp
index 389979f..3f4c46d 100644
--- a/include/rive/animation/transition_value_color_comparator.hpp
+++ b/include/rive/animation/transition_value_color_comparator.hpp
@@ -5,13 +5,7 @@
 namespace rive
 {
 class TransitionValueColorComparator : public TransitionValueColorComparatorBase
-{
-public:
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_value_id_comparator.hpp b/include/rive/animation/transition_value_id_comparator.hpp
index 6eea53b..f4bd07f 100644
--- a/include/rive/animation/transition_value_id_comparator.hpp
+++ b/include/rive/animation/transition_value_id_comparator.hpp
@@ -5,9 +5,7 @@
 namespace rive
 {
 class TransitionValueIdComparator : public TransitionValueIdComparatorBase
-{
-public:
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_value_number_comparator.hpp b/include/rive/animation/transition_value_number_comparator.hpp
index 649768f..a752e30 100644
--- a/include/rive/animation/transition_value_number_comparator.hpp
+++ b/include/rive/animation/transition_value_number_comparator.hpp
@@ -6,13 +6,7 @@
 {
 class TransitionValueNumberComparator
     : public TransitionValueNumberComparatorBase
-{
-public:
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_value_string_comparator.hpp b/include/rive/animation/transition_value_string_comparator.hpp
index 4288c7e..8b647e1 100644
--- a/include/rive/animation/transition_value_string_comparator.hpp
+++ b/include/rive/animation/transition_value_string_comparator.hpp
@@ -6,13 +6,7 @@
 {
 class TransitionValueStringComparator
     : public TransitionValueStringComparatorBase
-{
-public:
-    bool compare(TransitionComparator* comparand,
-                 TransitionConditionOp operation,
-                 const StateMachineInstance* stateMachineInstance,
-                 StateMachineLayerInstance* layerInstance) override;
-};
+{};
 } // namespace rive
 
 #endif
\ No newline at end of file
diff --git a/include/rive/animation/transition_viewmodel_condition.hpp b/include/rive/animation/transition_viewmodel_condition.hpp
index 8891407..50a1a82 100644
--- a/include/rive/animation/transition_viewmodel_condition.hpp
+++ b/include/rive/animation/transition_viewmodel_condition.hpp
@@ -2,16 +2,566 @@
 #define _RIVE_TRANSITION_VIEW_MODEL_CONDITION_HPP_
 #include "rive/generated/animation/transition_viewmodel_condition_base.hpp"
 #include "rive/animation/transition_comparator.hpp"
+#include "rive/animation/transition_property_artboard_comparator.hpp"
+#include "rive/animation/transition_property_viewmodel_comparator.hpp"
 #include "rive/animation/transition_condition_op.hpp"
 #include "rive/animation/state_machine_instance.hpp"
+#include "rive/data_bind/bindable_property.hpp"
+#include "rive/data_bind/bindable_property_artboard.hpp"
+#include "rive/data_bind/bindable_property_asset.hpp"
+#include "rive/data_bind/bindable_property_boolean.hpp"
+#include "rive/data_bind/bindable_property_color.hpp"
+#include "rive/data_bind/bindable_property_enum.hpp"
+#include "rive/data_bind/bindable_property_integer.hpp"
+#include "rive/data_bind/bindable_property_number.hpp"
+#include "rive/data_bind/bindable_property_string.hpp"
+#include "rive/data_bind/bindable_property_trigger.hpp"
+#include "rive/animation/transition_self_comparator.hpp"
+#include "rive/animation/transition_value_artboard_comparator.hpp"
+#include "rive/animation/transition_value_asset_comparator.hpp"
+#include "rive/animation/transition_value_number_comparator.hpp"
+#include "rive/animation/transition_value_boolean_comparator.hpp"
+#include "rive/animation/transition_value_string_comparator.hpp"
+#include "rive/animation/transition_value_color_comparator.hpp"
+#include "rive/animation/transition_value_enum_comparator.hpp"
+#include "rive/animation/transition_value_trigger_comparator.hpp"
+#include "rive/animation/artboard_property.hpp"
 #include <stdio.h>
 namespace rive
 {
+
+class ConditionOperation
+{
+public:
+    virtual ~ConditionOperation() {}
+    virtual bool compareNumbers(float a, float b) { return false; };
+    virtual bool compareBooleans(bool a, bool b) { return false; }
+    virtual bool compareStrings(const std::string& a, const std::string& b)
+    {
+        return false;
+    }
+    virtual bool compareInts(int a, int b) { return false; }
+    virtual bool compareUints32(uint32_t a, uint32_t b) { return false; }
+
+protected:
+    template <typename T> bool equal(T left, T right) { return left == right; }
+    template <typename T> bool notEqual(T left, T right)
+    {
+        return left != right;
+    }
+    template <typename T> bool lessThanOrEqual(T left, T right)
+    {
+        return left <= right;
+    }
+    template <typename T> bool lessThan(T left, T right)
+    {
+        return left < right;
+    }
+    template <typename T> bool greaterThanOrEqual(T left, T right)
+    {
+        return left >= right;
+    }
+    template <typename T> bool greaterThan(T left, T right)
+    {
+        return left > right;
+    }
+};
+class ConditionOperationEqual : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return equal<float>(a, b);
+    }
+    bool compareBooleans(bool a, bool b) override { return equal<bool>(a, b); }
+    bool compareStrings(const std::string& a, const std::string& b) override
+    {
+        return equal<std::string>(a, b);
+    }
+    bool compareInts(int a, int b) override { return equal<int>(a, b); }
+    bool compareUints32(uint32_t a, uint32_t b) override
+    {
+        return equal<uint32_t>(a, b);
+    }
+};
+class ConditionOperationNotEqual : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return notEqual<float>(a, b);
+    }
+    bool compareBooleans(bool a, bool b) override
+    {
+        return notEqual<bool>(a, b);
+    }
+    bool compareStrings(const std::string& a, const std::string& b) override
+    {
+        return notEqual<std::string>(a, b);
+    }
+    bool compareInts(int a, int b) override { return notEqual<int>(a, b); }
+    bool compareUints32(uint32_t a, uint32_t b) override
+    {
+        return notEqual<uint32_t>(a, b);
+    }
+};
+class ConditionOperationLessThanOrEqual : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return lessThanOrEqual<float>(a, b);
+    }
+};
+class ConditionOperationLessThan : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return lessThan<float>(a, b);
+    }
+};
+class ConditionOperationGreaterThanOrEqual : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return greaterThanOrEqual<float>(a, b);
+    }
+};
+class ConditionOperationGreaterThan : public ConditionOperation
+{
+public:
+    bool compareNumbers(float a, float b) override
+    {
+        return greaterThan<float>(a, b);
+    }
+};
+class ConditionComparand
+{};
+
+class ConditionComparandNumber : public ConditionComparand
+{
+public:
+    virtual ~ConditionComparandNumber() {}
+    virtual float value(const StateMachineInstance* stateMachineInstance) = 0;
+};
+class ConditionComparandNumberBindable : public ConditionComparandNumber
+{
+public:
+    ConditionComparandNumberBindable(BindablePropertyNumber* property) :
+        m_bindableProperty(property)
+    {}
+    float value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyNumber>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyNumber* m_bindableProperty;
+};
+class ConditionComparandArtboardProperty : public ConditionComparandNumber
+{
+public:
+    ConditionComparandArtboardProperty(
+        TransitionPropertyArtboardComparator* property) :
+        m_transitionPropertyArtboardComparator(property)
+    {}
+    float value(const StateMachineInstance* stateMachineInstance) override
+    {
+
+        auto artboard = stateMachineInstance->artboard();
+        if (artboard != nullptr)
+        {
+            auto property = static_cast<ArtboardProperty>(
+                m_transitionPropertyArtboardComparator->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;
+    }
+
+private:
+    TransitionPropertyArtboardComparator*
+        m_transitionPropertyArtboardComparator;
+};
+
+class ConditionComparandNumberBindableInteger : public ConditionComparandNumber
+{
+public:
+    ConditionComparandNumberBindableInteger(BindablePropertyInteger* property) :
+        m_bindableProperty(property)
+    {}
+    float value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+
+            return (float)bindableInstance->as<BindablePropertyInteger>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyInteger* m_bindableProperty;
+};
+class ConditionComparandNumberValue : public ConditionComparandNumber
+{
+public:
+    ConditionComparandNumberValue(TransitionValueNumberComparator* value) :
+        m_value(value)
+    {}
+    float value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueNumberComparator* m_value;
+};
+
+class ConditionComparandBoolean : public ConditionComparand
+{
+public:
+    virtual ~ConditionComparandBoolean() {}
+    virtual bool value(const StateMachineInstance* stateMachineInstance) = 0;
+};
+class ConditionComparandBooleanBindable : public ConditionComparandBoolean
+{
+public:
+    ConditionComparandBooleanBindable(BindablePropertyBoolean* property) :
+        m_bindableProperty(property)
+    {}
+    bool value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyBoolean>()
+                ->propertyValue();
+        }
+        return false;
+    }
+
+private:
+    BindablePropertyBoolean* m_bindableProperty;
+};
+class ConditionComparandBooleanValue : public ConditionComparandBoolean
+{
+public:
+    ConditionComparandBooleanValue(TransitionValueBooleanComparator* value) :
+        m_value(value)
+    {}
+    bool value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueBooleanComparator* m_value;
+};
+
+class ConditionComparandString : public ConditionComparand
+{
+public:
+    virtual ~ConditionComparandString() {}
+    virtual std::string value(
+        const StateMachineInstance* stateMachineInstance) = 0;
+};
+class ConditionComparandStringBindable : public ConditionComparandString
+{
+public:
+    ConditionComparandStringBindable(BindablePropertyString* property) :
+        m_bindableProperty(property)
+    {}
+    std::string value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyString>()
+                ->propertyValue();
+        }
+        return std::string{};
+    }
+
+private:
+    BindablePropertyString* m_bindableProperty;
+};
+class ConditionComparandStringValue : public ConditionComparandString
+{
+public:
+    ConditionComparandStringValue(TransitionValueStringComparator* value) :
+        m_value(value)
+    {}
+    std::string value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueStringComparator* m_value;
+};
+
+class ConditionComparandColor : public ConditionComparand
+{
+public:
+    virtual ~ConditionComparandColor() {}
+    virtual int value(const StateMachineInstance* stateMachineInstance) = 0;
+};
+class ConditionComparandColorBindable : public ConditionComparandColor
+{
+public:
+    ConditionComparandColorBindable(BindablePropertyColor* property) :
+        m_bindableProperty(property)
+    {}
+    int value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyColor>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyColor* m_bindableProperty;
+};
+class ConditionComparandColorValue : public ConditionComparandColor
+{
+public:
+    ConditionComparandColorValue(TransitionValueColorComparator* value) :
+        m_value(value)
+    {}
+    int value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueColorComparator* m_value;
+};
+
+class ConditionComparandUint32 : public ConditionComparand
+{
+public:
+    virtual ~ConditionComparandUint32() {}
+    virtual uint32_t value(
+        const StateMachineInstance* stateMachineInstance) = 0;
+};
+class ConditionComparandEnumBindable : public ConditionComparandUint32
+{
+public:
+    ConditionComparandEnumBindable(BindablePropertyEnum* property) :
+        m_bindableProperty(property)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyEnum>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyEnum* m_bindableProperty;
+};
+class ConditionComparandEnumValue : public ConditionComparandUint32
+{
+public:
+    ConditionComparandEnumValue(TransitionValueEnumComparator* value) :
+        m_value(value)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueEnumComparator* m_value;
+};
+class ConditionComparandTriggerBindable : public ConditionComparandUint32
+{
+public:
+    ConditionComparandTriggerBindable(BindablePropertyTrigger* property) :
+        m_bindableProperty(property)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyTrigger>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyTrigger* m_bindableProperty;
+};
+class ConditionComparandTriggerValue : public ConditionComparandUint32
+{
+public:
+    ConditionComparandTriggerValue(TransitionValueTriggerComparator* value) :
+        m_value(value)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueTriggerComparator* m_value;
+};
+class ConditionComparandIntegerBindable : public ConditionComparandNumber
+{
+public:
+    ConditionComparandIntegerBindable(BindablePropertyInteger* property) :
+        m_bindableProperty(property)
+    {}
+    float value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return (float)bindableInstance->as<BindablePropertyInteger>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyInteger* m_bindableProperty;
+};
+class ConditionComparandAssetBindable : public ConditionComparandUint32
+{
+public:
+    ConditionComparandAssetBindable(BindablePropertyAsset* property) :
+        m_bindableProperty(property)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyAsset>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyAsset* m_bindableProperty;
+};
+class ConditionComparandAssetValue : public ConditionComparandUint32
+{
+public:
+    ConditionComparandAssetValue(TransitionValueAssetComparator* value) :
+        m_value(value)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueAssetComparator* m_value;
+};
+class ConditionComparandArtboardBindable : public ConditionComparandUint32
+{
+public:
+    ConditionComparandArtboardBindable(BindablePropertyArtboard* property) :
+        m_bindableProperty(property)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        if (bindableInstance)
+        {
+            return bindableInstance->as<BindablePropertyArtboard>()
+                ->propertyValue();
+        }
+        return 0;
+    }
+
+private:
+    BindablePropertyArtboard* m_bindableProperty;
+};
+class ConditionComparandArtboardValue : public ConditionComparandUint32
+{
+public:
+    ConditionComparandArtboardValue(TransitionValueArtboardComparator* value) :
+        m_value(value)
+    {}
+    uint32_t value(const StateMachineInstance* stateMachineInstance) override
+    {
+        return m_value->value();
+    }
+
+private:
+    TransitionValueArtboardComparator* m_value;
+};
+
+class ConditionComparison
+{
+public:
+    ConditionComparison(ConditionOperation* op) : m_operation(op) {}
+    virtual ~ConditionComparison() { delete m_operation; }
+    virtual bool compare(const StateMachineInstance* stateMachineInstance,
+                         StateMachineLayerInstance* layerInstance) = 0;
+
+    bool compareNumbers(float left, float right);
+    bool compareBooleans(bool left, bool right);
+    bool compareStrings(const std::string& left, const std::string& right);
+    bool compareColors(int left, int right);
+    bool compareUints32(uint32_t left, uint32_t right);
+
+protected:
+    ConditionOperation* m_operation;
+};
 class TransitionViewModelCondition : public TransitionViewModelConditionBase
 {
 protected:
     TransitionComparator* m_leftComparator;
     TransitionComparator* m_rightComparator;
+    ConditionComparison* m_comparison = nullptr;
 
 public:
     ~TransitionViewModelCondition();
@@ -36,6 +586,8 @@
     {
         return (TransitionConditionOp)opValue();
     }
+    ConditionOperation* operation(TransitionConditionOp op);
+    void initialize();
 };
 } // namespace rive
 
diff --git a/include/rive/importers/transition_viewmodel_condition_importer.hpp b/include/rive/importers/transition_viewmodel_condition_importer.hpp
index 7cf92bd..45dda8c 100644
--- a/include/rive/importers/transition_viewmodel_condition_importer.hpp
+++ b/include/rive/importers/transition_viewmodel_condition_importer.hpp
@@ -18,6 +18,7 @@
     TransitionViewModelConditionImporter(
         TransitionViewModelCondition* transitionViewModelCondition);
     void setComparator(TransitionComparator* comparator);
+    StatusCode resolve() override;
 };
 } // namespace rive
 #endif
\ No newline at end of file
diff --git a/src/animation/transition_comparator.cpp b/src/animation/transition_comparator.cpp
index c7f7f03..415eea8 100644
--- a/src/animation/transition_comparator.cpp
+++ b/src/animation/transition_comparator.cpp
@@ -16,62 +16,4 @@
     }
     transitionViewModelConditionImporter->setComparator(this);
     return Super::import(importStack);
-}
-
-bool TransitionComparator::compareNumbers(float left,
-                                          float right,
-                                          TransitionConditionOp op)
-{
-    return compareComparables<float>(left, right, op);
-}
-
-bool TransitionComparator::compareStrings(std::string left,
-                                          std::string right,
-                                          TransitionConditionOp op)
-{
-    return compareComparables<std::string>(left, right, op);
-}
-
-bool TransitionComparator::compareBooleans(bool left,
-                                           bool right,
-                                           TransitionConditionOp op)
-{
-    return compareComparables<bool>(left, right, op);
-}
-
-bool TransitionComparator::compareEnums(uint16_t left,
-                                        uint16_t right,
-                                        TransitionConditionOp op)
-{
-    return compareComparables<uint16_t>(left, right, op);
-}
-
-bool TransitionComparator::compareTriggers(uint32_t left,
-                                           uint32_t right,
-                                           TransitionConditionOp op)
-{
-    return compareComparables<uint32_t>(left, right, op);
-}
-
-bool TransitionComparator::compareIds(uint32_t left,
-                                      uint32_t right,
-                                      TransitionConditionOp op)
-{
-    return compareComparables<uint32_t>(left, right, op);
-}
-
-bool TransitionComparator::compareColors(int left,
-                                         int right,
-                                         TransitionConditionOp op)
-{
-    return compareComparables<int>(left, right, op);
-}
-
-bool TransitionComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    return false;
 }
\ No newline at end of file
diff --git a/src/animation/transition_property_artboard_comparator.cpp b/src/animation/transition_property_artboard_comparator.cpp
deleted file mode 100644
index 1b0d14c..0000000
--- a/src/animation/transition_property_artboard_comparator.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#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,
-    StateMachineLayerInstance* layerInstance)
-{
-    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/animation/transition_property_viewmodel_comparator.cpp b/src/animation/transition_property_viewmodel_comparator.cpp
index 54eed36..3287059 100644
--- a/src/animation/transition_property_viewmodel_comparator.cpp
+++ b/src/animation/transition_property_viewmodel_comparator.cpp
@@ -47,289 +47,6 @@
     return Super::import(importStack);
 }
 
-float TransitionPropertyViewModelComparator::valueToFloat(
-    const StateMachineInstance* stateMachineInstance)
-{
-    auto bindableInstance =
-        stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
-    if (bindableInstance != nullptr)
-    {
-        if (bindableInstance->is<BindablePropertyInteger>())
-        {
-            return (float)this->value<BindablePropertyInteger, uint32_t>(
-                stateMachineInstance);
-        }
-        else if (bindableInstance->is<BindablePropertyNumber>())
-        {
-            return this->value<BindablePropertyNumber, float>(
-                stateMachineInstance);
-        }
-    }
-    return 0;
-}
-
-bool TransitionPropertyViewModelComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    if (comparand->is<TransitionSelfComparator>())
-    {
-        auto bindableInstance =
-            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
-        auto dataBind =
-            stateMachineInstance->bindableDataBindToTarget(bindableInstance);
-        if (dataBind != nullptr)
-        {
-            auto source = dataBind->source();
-            if (source != nullptr && source->hasChanged())
-            {
-                if (source->isUsedInLayer(layerInstance))
-                {
-
-                    return false;
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-    switch (m_bindableProperty->coreType())
-    {
-        case BindablePropertyNumber::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->valueToFloat(stateMachineInstance);
-                return compareNumbers(valueToFloat(stateMachineInstance),
-                                      rightValue,
-                                      operation);
-            }
-            else if (comparand->is<TransitionValueNumberComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueNumberComparator>()->value();
-                return compareNumbers(valueToFloat(stateMachineInstance),
-                                      rightValue,
-                                      operation);
-            }
-            break;
-        case BindablePropertyString::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyString, std::string>(
-                            stateMachineInstance);
-                return compareStrings(
-                    value<BindablePropertyString, std::string>(
-                        stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            else if (comparand->is<TransitionValueStringComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueStringComparator>()->value();
-                return compareStrings(
-                    value<BindablePropertyString, std::string>(
-                        stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            break;
-        case BindablePropertyColor::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyColor, int>(
-                            stateMachineInstance);
-                return compareColors(
-                    value<BindablePropertyColor, int>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            else if (comparand->is<TransitionValueColorComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueColorComparator>()->value();
-                return compareColors(
-                    value<BindablePropertyColor, int>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            break;
-        case BindablePropertyBoolean::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyBoolean, bool>(
-                            stateMachineInstance);
-                return compareBooleans(
-                    value<BindablePropertyBoolean, bool>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            else if (comparand->is<TransitionValueBooleanComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueBooleanComparator>()->value();
-                return compareBooleans(
-                    value<BindablePropertyBoolean, bool>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            break;
-        case BindablePropertyEnum::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyEnum, uint16_t>(
-                            stateMachineInstance);
-                return compareEnums(
-                    value<BindablePropertyEnum, uint16_t>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            else if (comparand->is<TransitionValueEnumComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueEnumComparator>()->value();
-                return compareEnums(
-                    value<BindablePropertyEnum, uint16_t>(stateMachineInstance),
-                    rightValue,
-                    operation);
-            }
-            break;
-        case BindablePropertyTrigger::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyTrigger, uint32_t>(
-                            stateMachineInstance);
-                return compareTriggers(value<BindablePropertyTrigger, uint32_t>(
-                                           stateMachineInstance),
-                                       rightValue,
-                                       operation);
-            }
-            else if (comparand->is<TransitionValueTriggerComparator>())
-            {
-                auto bindableInstance =
-                    stateMachineInstance->bindablePropertyInstance(
-                        m_bindableProperty);
-                auto dataBind = stateMachineInstance->bindableDataBindToTarget(
-                    bindableInstance);
-                if (dataBind != nullptr)
-                {
-                    auto source = dataBind->source();
-                    if (source != nullptr &&
-                        source->is<ViewModelInstanceTrigger>())
-                    {
-                        if (source->as<ViewModelInstanceTrigger>()
-                                ->isUsedInLayer(layerInstance))
-                        {
-
-                            return false;
-                        }
-                    }
-                }
-                auto leftValue = value<BindablePropertyTrigger, uint32_t>(
-                    stateMachineInstance);
-                if (leftValue != 0)
-                {
-                    return true;
-                }
-            }
-            break;
-        case BindablePropertyInteger::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->valueToFloat(stateMachineInstance);
-                return compareNumbers(valueToFloat(stateMachineInstance),
-                                      rightValue,
-                                      operation);
-            }
-            else if (comparand->is<TransitionValueNumberComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueNumberComparator>()->value();
-                switch (instanceDataType(stateMachineInstance))
-                {
-                    case DataType::number:
-                        return compareNumbers(
-                            valueToFloat(stateMachineInstance),
-                            rightValue,
-                            operation);
-                    case DataType::integer:
-                    {
-
-                        auto val = value<BindablePropertyInteger, uint32_t>(
-                            stateMachineInstance);
-                        return compareNumbers((float)val,
-                                              rightValue,
-                                              operation);
-                    }
-                    default:
-                        break;
-                }
-            }
-            break;
-        case BindablePropertyAsset::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyAsset, uint32_t>(
-                            stateMachineInstance);
-                return compareIds(value<BindablePropertyAsset, uint32_t>(
-                                      stateMachineInstance),
-                                  rightValue,
-                                  operation);
-            }
-            else if (comparand->is<TransitionValueAssetComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueAssetComparator>()->value();
-                return compareIds(value<BindablePropertyAsset, uint32_t>(
-                                      stateMachineInstance),
-                                  rightValue,
-                                  operation);
-            }
-            break;
-        case BindablePropertyArtboard::typeKey:
-            if (comparand->is<TransitionPropertyViewModelComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionPropertyViewModelComparator>()
-                        ->value<BindablePropertyArtboard, uint32_t>(
-                            stateMachineInstance);
-                return compareIds(value<BindablePropertyArtboard, uint32_t>(
-                                      stateMachineInstance),
-                                  rightValue,
-                                  operation);
-            }
-            else if (comparand->is<TransitionValueArtboardComparator>())
-            {
-                auto rightValue =
-                    comparand->as<TransitionValueArtboardComparator>()->value();
-                return compareIds(value<BindablePropertyArtboard, uint32_t>(
-                                      stateMachineInstance),
-                                  rightValue,
-                                  operation);
-            }
-            break;
-    }
-    return false;
-}
-
 void TransitionPropertyViewModelComparator::useInLayer(
     const StateMachineInstance* stateMachineInstance,
     StateMachineLayerInstance* layerInstance) const
@@ -348,34 +65,4 @@
     {
         source->useInLayer(layerInstance);
     }
-}
-
-DataType TransitionPropertyViewModelComparator::instanceDataType(
-    const StateMachineInstance* stateMachineInstance)
-{
-    auto bindableInstance =
-        stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
-    if (bindableInstance != nullptr)
-    {
-
-        switch (bindableInstance->coreType())
-        {
-            case BindablePropertyNumberBase::typeKey:
-
-                return DataType::number;
-            case BindablePropertyBooleanBase::typeKey:
-                return DataType::boolean;
-            case BindablePropertyColorBase::typeKey:
-                return DataType::color;
-            case BindablePropertyStringBase::typeKey:
-                return DataType::string;
-            case BindablePropertyEnumBase::typeKey:
-                return DataType::enumType;
-            case BindablePropertyTriggerBase::typeKey:
-                return DataType::trigger;
-            case BindablePropertyIntegerBase::typeKey:
-                return DataType::integer;
-        }
-    }
-    return DataType::none;
 }
\ No newline at end of file
diff --git a/src/animation/transition_value_boolean_comparator.cpp b/src/animation/transition_value_boolean_comparator.cpp
deleted file mode 100644
index 7d54883..0000000
--- a/src/animation/transition_value_boolean_comparator.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "rive/animation/transition_value_boolean_comparator.hpp"
-
-using namespace rive;
-
-bool TransitionValueBooleanComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    if (comparand->is<TransitionValueBooleanComparator>())
-    {
-        return compareBooleans(
-            value(),
-            comparand->as<TransitionValueBooleanComparator>()->value(),
-            operation);
-    }
-    return false;
-}
\ No newline at end of file
diff --git a/src/animation/transition_value_color_comparator.cpp b/src/animation/transition_value_color_comparator.cpp
deleted file mode 100644
index 20ad28d..0000000
--- a/src/animation/transition_value_color_comparator.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "rive/animation/transition_value_color_comparator.hpp"
-
-using namespace rive;
-
-bool TransitionValueColorComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    if (comparand->is<TransitionValueColorComparator>())
-    {
-        return compareColors(
-            value(),
-            comparand->as<TransitionValueColorComparator>()->value(),
-            operation);
-    }
-    return false;
-}
\ No newline at end of file
diff --git a/src/animation/transition_value_enum_comparator.cpp b/src/animation/transition_value_enum_comparator.cpp
deleted file mode 100644
index 8742e37..0000000
--- a/src/animation/transition_value_enum_comparator.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "rive/animation/transition_value_enum_comparator.hpp"
-#include "rive/viewmodel/viewmodel_instance_enum.hpp"
-
-using namespace rive;
\ No newline at end of file
diff --git a/src/animation/transition_value_number_comparator.cpp b/src/animation/transition_value_number_comparator.cpp
deleted file mode 100644
index 5f4aa10..0000000
--- a/src/animation/transition_value_number_comparator.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "rive/animation/transition_value_number_comparator.hpp"
-
-using namespace rive;
-
-bool TransitionValueNumberComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    if (comparand->is<TransitionValueNumberComparator>())
-    {
-        return compareNumbers(
-            value(),
-            comparand->as<TransitionValueNumberComparator>()->value(),
-            operation);
-    }
-    return false;
-}
\ No newline at end of file
diff --git a/src/animation/transition_value_string_comparator.cpp b/src/animation/transition_value_string_comparator.cpp
deleted file mode 100644
index 5b6e85e..0000000
--- a/src/animation/transition_value_string_comparator.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "rive/animation/transition_value_string_comparator.hpp"
-
-using namespace rive;
-
-bool TransitionValueStringComparator::compare(
-    TransitionComparator* comparand,
-    TransitionConditionOp operation,
-    const StateMachineInstance* stateMachineInstance,
-    StateMachineLayerInstance* layerInstance)
-{
-    if (comparand->is<TransitionValueStringComparator>())
-    {
-        return compareStrings(
-            value(),
-            comparand->as<TransitionValueStringComparator>()->value(),
-            operation);
-    }
-    return false;
-}
\ No newline at end of file
diff --git a/src/animation/transition_viewmodel_condition.cpp b/src/animation/transition_viewmodel_condition.cpp
index 8178aab..10f3f8f 100644
--- a/src/animation/transition_viewmodel_condition.cpp
+++ b/src/animation/transition_viewmodel_condition.cpp
@@ -8,6 +8,206 @@
 
 using namespace rive;
 
+class ConditionComparisonNone : public ConditionComparison
+{
+public:
+    ConditionComparisonNone() : ConditionComparison(nullptr) {}
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return false;
+    }
+};
+
+class ConditionComparisonSelf : public ConditionComparison
+{
+public:
+    ConditionComparisonSelf(BindableProperty* property) :
+        ConditionComparison(nullptr), m_bindableProperty(property)
+    {}
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        auto bindableInstance =
+            stateMachineInstance->bindablePropertyInstance(m_bindableProperty);
+        auto dataBind =
+            stateMachineInstance->bindableDataBindToTarget(bindableInstance);
+        if (dataBind != nullptr)
+        {
+            auto source = dataBind->source();
+            if (source != nullptr && source->hasChanged() &&
+                !source->isUsedInLayer(layerInstance))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+private:
+    BindableProperty* m_bindableProperty;
+};
+class ConditionComparisonNumber : public ConditionComparison
+{
+public:
+    ConditionComparisonNumber(ConditionComparandNumber* left,
+                              ConditionComparandNumber* right,
+                              ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonNumber()
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareNumbers(m_leftComparand->value(stateMachineInstance),
+                              m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandNumber* m_leftComparand = nullptr;
+    ConditionComparandNumber* m_rightComparand = nullptr;
+};
+class ConditionComparisonBoolean : public ConditionComparison
+{
+public:
+    ConditionComparisonBoolean(ConditionComparandBoolean* left,
+                               ConditionComparandBoolean* right,
+                               ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonBoolean() override
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareBooleans(m_leftComparand->value(stateMachineInstance),
+                               m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandBoolean* m_leftComparand = nullptr;
+    ConditionComparandBoolean* m_rightComparand = nullptr;
+};
+
+class ConditionComparisonString : public ConditionComparison
+{
+public:
+    ConditionComparisonString(ConditionComparandString* left,
+                              ConditionComparandString* right,
+                              ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonString()
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareStrings(m_leftComparand->value(stateMachineInstance),
+                              m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandString* m_leftComparand = nullptr;
+    ConditionComparandString* m_rightComparand = nullptr;
+};
+
+class ConditionComparisonColor : public ConditionComparison
+{
+public:
+    ConditionComparisonColor(ConditionComparandColor* left,
+                             ConditionComparandColor* right,
+                             ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonColor()
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareColors(m_leftComparand->value(stateMachineInstance),
+                             m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandColor* m_leftComparand = nullptr;
+    ConditionComparandColor* m_rightComparand = nullptr;
+};
+
+class ConditionComparisonEnum : public ConditionComparison
+{
+public:
+    ConditionComparisonEnum(ConditionComparandUint32* left,
+                            ConditionComparandUint32* right,
+                            ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonEnum()
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareUints32(m_leftComparand->value(stateMachineInstance),
+                              m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandUint32* m_leftComparand = nullptr;
+    ConditionComparandUint32* m_rightComparand = nullptr;
+};
+
+class ConditionComparisonUint32 : public ConditionComparison
+{
+public:
+    ConditionComparisonUint32(ConditionComparandUint32* left,
+                              ConditionComparandUint32* right,
+                              ConditionOperation* operation) :
+        ConditionComparison(operation),
+        m_leftComparand(left),
+        m_rightComparand(right)
+    {}
+    ~ConditionComparisonUint32()
+    {
+        delete m_leftComparand;
+        delete m_rightComparand;
+    }
+    bool compare(const StateMachineInstance* stateMachineInstance,
+                 StateMachineLayerInstance* layerInstance) override
+    {
+        return compareUints32(m_leftComparand->value(stateMachineInstance),
+                              m_rightComparand->value(stateMachineInstance));
+    }
+
+private:
+    ConditionComparandUint32* m_leftComparand = nullptr;
+    ConditionComparandUint32* m_rightComparand = nullptr;
+};
+
 TransitionViewModelCondition::~TransitionViewModelCondition()
 {
     if (m_leftComparator != nullptr)
@@ -20,19 +220,20 @@
         delete m_rightComparator;
         m_rightComparator = nullptr;
     }
+    if (m_comparison != nullptr)
+    {
+        delete m_comparison;
+        m_comparison = nullptr;
+    }
 }
 
 bool TransitionViewModelCondition::evaluate(
     const StateMachineInstance* stateMachineInstance,
     StateMachineLayerInstance* layerInstance) const
 {
-    if (leftComparator() != nullptr && rightComparator() != nullptr &&
-        stateMachineInstance->dataContext())
+    if (stateMachineInstance->dataContext())
     {
-        return leftComparator()->compare(rightComparator(),
-                                         op(),
-                                         stateMachineInstance,
-                                         layerInstance);
+        return m_comparison->compare(stateMachineInstance, layerInstance);
     }
     return false;
 }
@@ -46,4 +247,507 @@
         return leftComparator()->useInLayer(stateMachineInstance,
                                             layerInstance);
     }
+}
+
+ConditionOperation* TransitionViewModelCondition::operation(
+    TransitionConditionOp op)
+{
+    switch (op)
+    {
+        case TransitionConditionOp::equal:
+            return new ConditionOperationEqual();
+        case TransitionConditionOp::notEqual:
+            return new ConditionOperationNotEqual();
+        case TransitionConditionOp::lessThanOrEqual:
+            return new ConditionOperationLessThanOrEqual();
+        case TransitionConditionOp::lessThan:
+            return new ConditionOperationLessThan();
+        case TransitionConditionOp::greaterThanOrEqual:
+            return new ConditionOperationGreaterThanOrEqual();
+        case TransitionConditionOp::greaterThan:
+            return new ConditionOperationGreaterThan();
+    }
+    return new ConditionOperation();
+}
+
+void TransitionViewModelCondition::initialize()
+{
+    if (leftComparator() && rightComparator())
+    {
+        if (leftComparator()->is<TransitionPropertyArtboardComparator>())
+        {
+
+            auto leftProperty =
+                leftComparator()->as<TransitionPropertyArtboardComparator>();
+            if (rightComparator()->is<TransitionPropertyViewModelComparator>())
+            {
+                auto rightBindableProperty =
+                    rightComparator()
+                        ->as<TransitionPropertyViewModelComparator>()
+                        ->bindableProperty();
+                if (rightBindableProperty->is<BindablePropertyNumber>())
+                {
+                    auto leftComparand =
+                        new ConditionComparandArtboardProperty(leftProperty);
+                    auto rightComparand = new ConditionComparandNumberBindable(
+                        rightBindableProperty->as<BindablePropertyNumber>());
+                    m_comparison =
+                        new ConditionComparisonNumber(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                else if (rightBindableProperty->is<BindablePropertyInteger>())
+                {
+                    auto leftComparand =
+                        new ConditionComparandArtboardProperty(leftProperty);
+                    auto rightComparand =
+                        new ConditionComparandNumberBindableInteger(
+                            rightBindableProperty
+                                ->as<BindablePropertyInteger>());
+                    m_comparison =
+                        new ConditionComparisonNumber(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+            }
+            else if (rightComparator()->is<TransitionValueNumberComparator>())
+            {
+                auto leftComparand =
+                    new ConditionComparandArtboardProperty(leftProperty);
+                auto rightComparand = new ConditionComparandNumberValue(
+                    rightComparator()->as<TransitionValueNumberComparator>());
+                m_comparison = new ConditionComparisonNumber(leftComparand,
+                                                             rightComparand,
+                                                             operation(op()));
+                return;
+            }
+        }
+        auto leftBindableProperty =
+            leftComparator()
+                ->as<TransitionPropertyViewModelComparator>()
+                ->bindableProperty();
+        if (rightComparator()->is<TransitionSelfComparator>())
+        {
+            m_comparison = new ConditionComparisonSelf(leftBindableProperty);
+            return;
+        }
+        switch (leftBindableProperty->coreType())
+        {
+            case BindablePropertyNumber::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyNumber>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandNumberBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyNumber>());
+                        auto rightComparand =
+                            new ConditionComparandNumberBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyNumber>());
+                        m_comparison =
+                            new ConditionComparisonNumber(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                    else if (rightBindableProperty
+                                 ->is<BindablePropertyInteger>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandNumberBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyNumber>());
+                        auto rightComparand =
+                            new ConditionComparandNumberBindableInteger(
+                                rightBindableProperty
+                                    ->as<BindablePropertyInteger>());
+                        m_comparison =
+                            new ConditionComparisonNumber(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueNumberComparator>())
+                {
+                    auto leftComparand = new ConditionComparandNumberBindable(
+                        leftBindableProperty->as<BindablePropertyNumber>());
+                    auto rightComparand = new ConditionComparandNumberValue(
+                        rightComparator()
+                            ->as<TransitionValueNumberComparator>());
+                    m_comparison =
+                        new ConditionComparisonNumber(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                break;
+            }
+
+            case BindablePropertyBoolean::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyBoolean>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandBooleanBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyBoolean>());
+                        auto rightComparand =
+                            new ConditionComparandBooleanBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyBoolean>());
+                        m_comparison =
+                            new ConditionComparisonBoolean(leftComparand,
+                                                           rightComparand,
+                                                           operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueBooleanComparator>())
+                {
+                    auto leftComparand = new ConditionComparandBooleanBindable(
+                        leftBindableProperty->as<BindablePropertyBoolean>());
+                    auto rightComparand = new ConditionComparandBooleanValue(
+                        rightComparator()
+                            ->as<TransitionValueBooleanComparator>());
+                    m_comparison =
+                        new ConditionComparisonBoolean(leftComparand,
+                                                       rightComparand,
+                                                       operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyString::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyString>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandStringBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyString>());
+                        auto rightComparand =
+                            new ConditionComparandStringBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyString>());
+                        m_comparison =
+                            new ConditionComparisonString(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueStringComparator>())
+                {
+                    auto leftComparand = new ConditionComparandStringBindable(
+                        leftBindableProperty->as<BindablePropertyString>());
+                    auto rightComparand = new ConditionComparandStringValue(
+                        rightComparator()
+                            ->as<TransitionValueStringComparator>());
+                    m_comparison =
+                        new ConditionComparisonString(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyColor::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyColor>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandColorBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyColor>());
+                        auto rightComparand =
+                            new ConditionComparandColorBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyColor>());
+                        m_comparison =
+                            new ConditionComparisonColor(leftComparand,
+                                                         rightComparand,
+                                                         operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueColorComparator>())
+                {
+                    auto leftComparand = new ConditionComparandColorBindable(
+                        leftBindableProperty->as<BindablePropertyColor>());
+                    auto rightComparand = new ConditionComparandColorValue(
+                        rightComparator()
+                            ->as<TransitionValueColorComparator>());
+                    m_comparison =
+                        new ConditionComparisonColor(leftComparand,
+                                                     rightComparand,
+                                                     operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyEnum::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyEnum>())
+                    {
+                        auto leftComparand = new ConditionComparandEnumBindable(
+                            leftBindableProperty->as<BindablePropertyEnum>());
+                        auto rightComparand =
+                            new ConditionComparandEnumBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyEnum>());
+                        m_comparison =
+                            new ConditionComparisonEnum(leftComparand,
+                                                        rightComparand,
+                                                        operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()->is<TransitionValueEnumComparator>())
+                {
+                    auto leftComparand = new ConditionComparandEnumBindable(
+                        leftBindableProperty->as<BindablePropertyEnum>());
+                    auto rightComparand = new ConditionComparandEnumValue(
+                        rightComparator()->as<TransitionValueEnumComparator>());
+                    m_comparison = new ConditionComparisonEnum(leftComparand,
+                                                               rightComparand,
+                                                               operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyTrigger::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyTrigger>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandTriggerBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyTrigger>());
+                        auto rightComparand =
+                            new ConditionComparandTriggerBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyTrigger>());
+                        m_comparison =
+                            new ConditionComparisonUint32(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueTriggerComparator>())
+                {
+                    m_comparison =
+                        new ConditionComparisonSelf(leftBindableProperty);
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyInteger::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyInteger>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandIntegerBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyInteger>());
+                        auto rightComparand =
+                            new ConditionComparandIntegerBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyInteger>());
+                        m_comparison =
+                            new ConditionComparisonNumber(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueNumberComparator>())
+                {
+                    auto leftComparand = new ConditionComparandIntegerBindable(
+                        leftBindableProperty->as<BindablePropertyInteger>());
+                    auto rightComparand = new ConditionComparandNumberValue(
+                        rightComparator()
+                            ->as<TransitionValueNumberComparator>());
+                    m_comparison =
+                        new ConditionComparisonNumber(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyAsset::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyAsset>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandAssetBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyAsset>());
+                        auto rightComparand =
+                            new ConditionComparandAssetBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyAsset>());
+                        m_comparison =
+                            new ConditionComparisonUint32(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueAssetComparator>())
+                {
+                    auto leftComparand = new ConditionComparandAssetBindable(
+                        leftBindableProperty->as<BindablePropertyAsset>());
+                    auto rightComparand = new ConditionComparandAssetValue(
+                        rightComparator()
+                            ->as<TransitionValueAssetComparator>());
+                    m_comparison =
+                        new ConditionComparisonUint32(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                break;
+            }
+            case BindablePropertyArtboard::typeKey:
+            {
+                if (rightComparator()
+                        ->is<TransitionPropertyViewModelComparator>())
+                {
+                    auto rightBindableProperty =
+                        rightComparator()
+                            ->as<TransitionPropertyViewModelComparator>()
+                            ->bindableProperty();
+                    if (rightBindableProperty->is<BindablePropertyArtboard>())
+                    {
+                        auto leftComparand =
+                            new ConditionComparandArtboardBindable(
+                                leftBindableProperty
+                                    ->as<BindablePropertyArtboard>());
+                        auto rightComparand =
+                            new ConditionComparandArtboardBindable(
+                                rightBindableProperty
+                                    ->as<BindablePropertyArtboard>());
+                        m_comparison =
+                            new ConditionComparisonUint32(leftComparand,
+                                                          rightComparand,
+                                                          operation(op()));
+                        return;
+                    }
+                }
+                else if (rightComparator()
+                             ->is<TransitionValueArtboardComparator>())
+                {
+                    auto leftComparand = new ConditionComparandArtboardBindable(
+                        leftBindableProperty->as<BindablePropertyArtboard>());
+                    auto rightComparand = new ConditionComparandArtboardValue(
+                        rightComparator()
+                            ->as<TransitionValueArtboardComparator>());
+                    m_comparison =
+                        new ConditionComparisonUint32(leftComparand,
+                                                      rightComparand,
+                                                      operation(op()));
+                    return;
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        m_comparison = new ConditionComparisonNone();
+    }
+}
+
+bool ConditionComparison::compareNumbers(float left, float right)
+{
+    return m_operation->compareNumbers(left, right);
+}
+
+bool ConditionComparison::compareStrings(const std::string& left,
+                                         const std::string& right)
+{
+    return m_operation->compareStrings(left, right);
+}
+
+bool ConditionComparison::compareBooleans(bool left, bool right)
+{
+    return m_operation->compareBooleans(left, right);
+}
+
+bool ConditionComparison::compareColors(int left, int right)
+{
+    return m_operation->compareInts(left, right);
+}
+
+bool ConditionComparison::compareUints32(uint32_t left, uint32_t right)
+{
+    return m_operation->compareUints32(left, right);
 }
\ No newline at end of file
diff --git a/src/importers/transition_viewmodel_condition_importer.cpp b/src/importers/transition_viewmodel_condition_importer.cpp
index 13108f1..5c71f7e 100644
--- a/src/importers/transition_viewmodel_condition_importer.cpp
+++ b/src/importers/transition_viewmodel_condition_importer.cpp
@@ -14,4 +14,10 @@
     TransitionComparator* comparator)
 {
     m_TransitionViewModelCondition->comparator(comparator);
+}
+
+StatusCode TransitionViewModelConditionImporter::resolve()
+{
+    m_TransitionViewModelCondition->initialize();
+    return StatusCode::Ok;
 }
\ No newline at end of file
diff --git a/tests/unit_tests/assets/transition_artboard_condition_test.riv b/tests/unit_tests/assets/transition_artboard_condition_test.riv
new file mode 100644
index 0000000..bbcfbf1
--- /dev/null
+++ b/tests/unit_tests/assets/transition_artboard_condition_test.riv
Binary files differ
diff --git a/tests/unit_tests/runtime/serialized_rendering_test.cpp b/tests/unit_tests/runtime/serialized_rendering_test.cpp
index ea29550..b8e8dec 100644
--- a/tests/unit_tests/runtime/serialized_rendering_test.cpp
+++ b/tests/unit_tests/runtime/serialized_rendering_test.cpp
@@ -1664,4 +1664,43 @@
     artboard->draw(renderer.get());
 
     CHECK(silver.matches("advance_blend_mode-vms"));
-}
\ No newline at end of file
+}
+
+TEST_CASE("Test State machine transition conditions based on artboards",
+          "[silver]")
+{
+    SerializingFactory silver;
+    auto file =
+        ReadRiveFile("assets/transition_artboard_condition_test.riv", &silver);
+
+    auto artboard = file->artboardDefault();
+    REQUIRE(artboard != nullptr);
+
+    silver.frameSize(artboard->width(), artboard->height());
+
+    auto stateMachine = artboard->stateMachineAt(0);
+    int viewModelId = artboard.get()->viewModelId();
+
+    auto vmi = viewModelId == -1
+                   ? file->createViewModelInstance(artboard.get())
+                   : file->createViewModelInstance(viewModelId, 0);
+
+    stateMachine->bindViewModelInstance(vmi);
+    stateMachine->advanceAndApply(0.0f);
+    auto renderer = silver.makeRenderer();
+    artboard->draw(renderer.get());
+
+    silver.addFrame();
+    stateMachine->advanceAndApply(0.016f);
+    artboard->draw(renderer.get());
+
+    int frames = (int)(1.0f / 0.016f);
+    for (int i = 0; i < frames; i++)
+    {
+        silver.addFrame();
+        stateMachine->advanceAndApply(0.016f);
+        artboard->draw(renderer.get());
+    }
+
+    CHECK(silver.matches("transition_artboard_condition_test"));
+}
diff --git a/tests/unit_tests/silvers/transition_artboard_condition_test.sriv b/tests/unit_tests/silvers/transition_artboard_condition_test.sriv
new file mode 100644
index 0000000..d66ade1
--- /dev/null
+++ b/tests/unit_tests/silvers/transition_artboard_condition_test.sriv
Binary files differ