add directBlendState by mix value, bypassing setting inputs

fixes https://github.com/rive-app/rive/issues/5039

lets you set integer values as input

https://user-images.githubusercontent.com/1216025/228241518-2d08812d-c283-4a15-a94d-9bb72544ecc3.mp4

todo (leaving because i want feedback first):
- [x] add tests
- [x] update cpp runtime
- [x] run `generate_core_runtime.sh`
- [x] run `generate_core.sh` for cpp

Diffs=
6df791fe4 add directBlendState by mix value, bypassing setting inputs (#5053)
diff --git a/.rive_head b/.rive_head
index afbd3bf..044102c 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-d9952ae77c4024134bbd067f53cc04c698c02dda
+6df791fe4cbf6f70dc026314400d88ce3fec0a79
diff --git a/dev/defs/animation/blend_animation_direct.json b/dev/defs/animation/blend_animation_direct.json
index af3601b..b15dfbb 100644
--- a/dev/defs/animation/blend_animation_direct.json
+++ b/dev/defs/animation/blend_animation_direct.json
@@ -16,6 +16,24 @@
         "string": "inputid"
       },
       "description": "Id of the input that drives the direct mix value for this animation."
+    },
+    "mixValue": {
+      "type": "double",
+      "initialValue": "1",
+      "key": {
+        "int": 297,
+        "string": "mixvalue"
+      },
+      "description": "Direct mix value for this animation."
+    },
+    "blendSource": {
+      "type": "uint",
+      "initialValue": "0",
+      "key": {
+        "int": 298,
+        "string": "blendsource"
+      },
+      "description": "Source to use when establishing the mix value for the animation. 0 means look at the input, 1 look at the mixValue."
     }
   }
-}
\ No newline at end of file
+}
diff --git a/include/rive/animation/blend_animation_direct.hpp b/include/rive/animation/blend_animation_direct.hpp
index 97355cd..f631ed5 100644
--- a/include/rive/animation/blend_animation_direct.hpp
+++ b/include/rive/animation/blend_animation_direct.hpp
@@ -4,6 +4,13 @@
 #include <stdio.h>
 namespace rive
 {
+
+enum class DirectBlendSource : unsigned int
+{
+    inputId = 0,
+    mixValue = 1,
+};
+
 class BlendAnimationDirect : public BlendAnimationDirectBase
 {
 public:
diff --git a/include/rive/generated/animation/blend_animation_direct_base.hpp b/include/rive/generated/animation/blend_animation_direct_base.hpp
index 74ce655..cb0f7bd 100644
--- a/include/rive/generated/animation/blend_animation_direct_base.hpp
+++ b/include/rive/generated/animation/blend_animation_direct_base.hpp
@@ -1,6 +1,7 @@
 #ifndef _RIVE_BLEND_ANIMATION_DIRECT_BASE_HPP_
 #define _RIVE_BLEND_ANIMATION_DIRECT_BASE_HPP_
 #include "rive/animation/blend_animation.hpp"
+#include "rive/core/field_types/core_double_type.hpp"
 #include "rive/core/field_types/core_uint_type.hpp"
 namespace rive
 {
@@ -29,9 +30,13 @@
     uint16_t coreType() const override { return typeKey; }
 
     static const uint16_t inputIdPropertyKey = 168;
+    static const uint16_t mixValuePropertyKey = 297;
+    static const uint16_t blendSourcePropertyKey = 298;
 
 private:
     uint32_t m_InputId = -1;
+    float m_MixValue = 1.0f;
+    uint32_t m_BlendSource = 0;
 
 public:
     inline uint32_t inputId() const { return m_InputId; }
@@ -45,10 +50,34 @@
         inputIdChanged();
     }
 
+    inline float mixValue() const { return m_MixValue; }
+    void mixValue(float value)
+    {
+        if (m_MixValue == value)
+        {
+            return;
+        }
+        m_MixValue = value;
+        mixValueChanged();
+    }
+
+    inline uint32_t blendSource() const { return m_BlendSource; }
+    void blendSource(uint32_t value)
+    {
+        if (m_BlendSource == value)
+        {
+            return;
+        }
+        m_BlendSource = value;
+        blendSourceChanged();
+    }
+
     Core* clone() const override;
     void copy(const BlendAnimationDirectBase& object)
     {
         m_InputId = object.m_InputId;
+        m_MixValue = object.m_MixValue;
+        m_BlendSource = object.m_BlendSource;
         BlendAnimation::copy(object);
     }
 
@@ -59,12 +88,20 @@
             case inputIdPropertyKey:
                 m_InputId = CoreUintType::deserialize(reader);
                 return true;
+            case mixValuePropertyKey:
+                m_MixValue = CoreDoubleType::deserialize(reader);
+                return true;
+            case blendSourcePropertyKey:
+                m_BlendSource = CoreUintType::deserialize(reader);
+                return true;
         }
         return BlendAnimation::deserialize(propertyKey, reader);
     }
 
 protected:
     virtual void inputIdChanged() {}
+    virtual void mixValueChanged() {}
+    virtual void blendSourceChanged() {}
 };
 } // namespace rive
 
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp
index d6f5af6..4688e77 100644
--- a/include/rive/generated/core_registry.hpp
+++ b/include/rive/generated/core_registry.hpp
@@ -406,6 +406,9 @@
             case BlendAnimationDirectBase::inputIdPropertyKey:
                 object->as<BlendAnimationDirectBase>()->inputId(value);
                 break;
+            case BlendAnimationDirectBase::blendSourcePropertyKey:
+                object->as<BlendAnimationDirectBase>()->blendSource(value);
+                break;
             case TransitionConditionBase::inputIdPropertyKey:
                 object->as<TransitionConditionBase>()->inputId(value);
                 break;
@@ -604,6 +607,9 @@
             case AdvanceableStateBase::speedPropertyKey:
                 object->as<AdvanceableStateBase>()->speed(value);
                 break;
+            case BlendAnimationDirectBase::mixValuePropertyKey:
+                object->as<BlendAnimationDirectBase>()->mixValue(value);
+                break;
             case StateMachineNumberBase::valuePropertyKey:
                 object->as<StateMachineNumberBase>()->value(value);
                 break;
@@ -966,6 +972,8 @@
                 return object->as<BlendAnimationBase>()->animationId();
             case BlendAnimationDirectBase::inputIdPropertyKey:
                 return object->as<BlendAnimationDirectBase>()->inputId();
+            case BlendAnimationDirectBase::blendSourcePropertyKey:
+                return object->as<BlendAnimationDirectBase>()->blendSource();
             case TransitionConditionBase::inputIdPropertyKey:
                 return object->as<TransitionConditionBase>()->inputId();
             case KeyedPropertyBase::propertyKeyPropertyKey:
@@ -1101,6 +1109,8 @@
                 return object->as<NestedSimpleAnimationBase>()->speed();
             case AdvanceableStateBase::speedPropertyKey:
                 return object->as<AdvanceableStateBase>()->speed();
+            case BlendAnimationDirectBase::mixValuePropertyKey:
+                return object->as<BlendAnimationDirectBase>()->mixValue();
             case StateMachineNumberBase::valuePropertyKey:
                 return object->as<StateMachineNumberBase>()->value();
             case CubicInterpolatorBase::x1PropertyKey:
@@ -1339,6 +1349,7 @@
             case KeyedObjectBase::objectIdPropertyKey:
             case BlendAnimationBase::animationIdPropertyKey:
             case BlendAnimationDirectBase::inputIdPropertyKey:
+            case BlendAnimationDirectBase::blendSourcePropertyKey:
             case TransitionConditionBase::inputIdPropertyKey:
             case KeyedPropertyBase::propertyKeyPropertyKey:
             case StateMachineListenerBase::targetIdPropertyKey:
@@ -1404,6 +1415,7 @@
             case NestedLinearAnimationBase::mixPropertyKey:
             case NestedSimpleAnimationBase::speedPropertyKey:
             case AdvanceableStateBase::speedPropertyKey:
+            case BlendAnimationDirectBase::mixValuePropertyKey:
             case StateMachineNumberBase::valuePropertyKey:
             case CubicInterpolatorBase::x1PropertyKey:
             case CubicInterpolatorBase::y1PropertyKey:
diff --git a/src/animation/blend_animation_direct.cpp b/src/animation/blend_animation_direct.cpp
index 98861a9..a9c175b 100644
--- a/src/animation/blend_animation_direct.cpp
+++ b/src/animation/blend_animation_direct.cpp
@@ -18,14 +18,17 @@
     }
 
     // Make sure the inputId doesn't overflow the input buffer.
-    if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount())
+    if (blendSource() == static_cast<int>(DirectBlendSource::inputId))
     {
-        return StatusCode::InvalidObject;
-    }
-    auto input = stateMachineImporter->stateMachine()->input((size_t)inputId());
-    if (input == nullptr || !input->is<StateMachineNumber>())
-    {
-        return StatusCode::InvalidObject;
+        if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount())
+        {
+            return StatusCode::InvalidObject;
+        }
+        auto input = stateMachineImporter->stateMachine()->input((size_t)inputId());
+        if (input == nullptr || !input->is<StateMachineNumber>())
+        {
+            return StatusCode::InvalidObject;
+        }
     }
     return Super::import(importStack);
 }
diff --git a/src/animation/blend_state_direct_instance.cpp b/src/animation/blend_state_direct_instance.cpp
index 09784b5..be42eaf 100644
--- a/src/animation/blend_state_direct_instance.cpp
+++ b/src/animation/blend_state_direct_instance.cpp
@@ -1,5 +1,8 @@
+
+#include "rive/animation/blend_animation_direct.hpp"
 #include "rive/animation/blend_state_direct_instance.hpp"
 #include "rive/animation/state_machine_input_instance.hpp"
+#include <iostream>
 
 using namespace rive;
 
@@ -13,10 +16,18 @@
     BlendStateInstance<BlendStateDirect, BlendAnimationDirect>::advance(seconds, inputs);
     for (auto& animation : m_AnimationInstances)
     {
-        auto inputInstance = inputs[animation.blendAnimation()->inputId()];
-
-        auto numberInput = static_cast<const SMINumber*>(inputInstance);
-        auto value = numberInput->value();
-        animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f)));
+        if (animation.blendAnimation()->blendSource() ==
+            static_cast<int>(DirectBlendSource::mixValue))
+        {
+            auto value = animation.blendAnimation()->mixValue();
+            animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f)));
+        }
+        else
+        {
+            auto inputInstance = inputs[animation.blendAnimation()->inputId()];
+            auto numberInput = static_cast<const SMINumber*>(inputInstance);
+            auto value = numberInput->value();
+            animation.mix(std::min(1.0f, std::max(0.0f, value / 100.0f)));
+        }
     }
 }