summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
authorkobewi <kobewi4e@gmail.com>2023-02-12 22:08:25 +0100
committerkobewi <kobewi4e@gmail.com>2023-02-12 22:08:25 +0100
commit17fe5c2b232d403c5101dbfe0adbf907dc037f5b (patch)
tree1fc05db3f9c3d22a8b1e1d5856e08519d69e5e55 /scene/animation
parent72c5b56d04f18c7ab078cb543d9dc68d05958d11 (diff)
Fix tween_method() type validation
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/tween.cpp30
-rw-r--r--scene/animation/tween.h2
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();