diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-02-12 22:34:41 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-02-12 22:34:41 +0100 |
commit | e3b07bf7b828023860e170ec06e5812c8ac6ad4f (patch) | |
tree | 180e57d81f8cd144314a4e3071d6721c84329856 | |
parent | 49e8a2fb6698de7e2dd248e8f846824dfbaccdb1 (diff) | |
parent | 17fe5c2b232d403c5101dbfe0adbf907dc037f5b (diff) |
Merge pull request #73178 from KoBeWi/tinder_for_types
Fix `tween_method()` type validation
-rw-r--r-- | scene/animation/tween.cpp | 30 | ||||
-rw-r--r-- | scene/animation/tween.h | 2 |
2 files changed, 22 insertions, 10 deletions
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index abc7814877..9d1118e0ef 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -60,6 +60,20 @@ void Tweener::_bind_methods() { ADD_SIGNAL(MethodInfo("finished")); } +bool Tween::_validate_type_match(const Variant &p_from, Variant &r_to) { + if (p_from.get_type() != r_to.get_type()) { + // Cast r_to between double and int to avoid minor annoyances. + if (p_from.get_type() == Variant::FLOAT && r_to.get_type() == Variant::INT) { + r_to = double(r_to); + } else if (p_from.get_type() == Variant::INT && r_to.get_type() == Variant::FLOAT) { + r_to = int(r_to); + } else { + ERR_FAIL_V_MSG(false, "Type mismatch between initial and final value: " + Variant::get_type_name(p_from.get_type()) + " and " + Variant::get_type_name(r_to.get_type())); + } + } + return true; +} + void Tween::_start_tweeners() { if (tweeners.is_empty()) { dead = true; @@ -85,16 +99,8 @@ Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); - Variant::Type property_type = p_target->get_indexed(p_property.get_as_property_path().get_subnames()).get_type(); - if (property_type != p_to.get_type()) { - // Cast p_to between double and int to avoid minor annoyances. - if (property_type == Variant::FLOAT && p_to.get_type() == Variant::INT) { - p_to = double(p_to); - } else if (property_type == Variant::INT && p_to.get_type() == Variant::FLOAT) { - p_to = int(p_to); - } else { - ERR_FAIL_V_MSG(Ref<PropertyTweener>(), "Type mismatch between property and final value: " + Variant::get_type_name(property_type) + " and " + Variant::get_type_name(p_to.get_type())); - } + if (!_validate_type_match(p_target->get_indexed(p_property.get_as_property_path().get_subnames()), p_to)) { + return nullptr; } Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration)); @@ -124,6 +130,10 @@ Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Vari ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); + if (!_validate_type_match(p_from, p_to)) { + return nullptr; + } + Ref<MethodTweener> tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration)); append(tweener); return tweener; diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 58217db535..c5abcb28a6 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -47,6 +47,7 @@ public: protected: static void _bind_methods(); + Ref<Tween> tween; double elapsed_time = 0; bool finished = false; @@ -125,6 +126,7 @@ private: void _start_tweeners(); void _stop_internal(bool p_reset); + bool _validate_type_match(const Variant &p_from, Variant &r_to); protected: static void _bind_methods(); |