|
34 | 34 | #include "scene/main/node.h" |
35 | 35 | #include "scene/resources/animation.h" |
36 | 36 |
|
37 | | -#define CHECK_VALID() \ |
38 | | - ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); \ |
39 | | - ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); |
| 37 | +#define CHECK_VALID() \ |
| 38 | + if (name.length() > 0) { \ |
| 39 | + ERR_FAIL_COND_V_MSG(!valid, nullptr, vformat("Tween \"%s\" invalid. Either finished or created outside scene tree.", name)); \ |
| 40 | + ERR_FAIL_COND_V_MSG(started, nullptr, vformat("Can't append to a Tween \"%s\" that has started. Use stop() first.", name)); \ |
| 41 | + } else { \ |
| 42 | + ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); \ |
| 43 | + ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); \ |
| 44 | + } |
40 | 45 |
|
41 | 46 | Tween::interpolater Tween::interpolaters[Tween::TRANS_MAX][Tween::EASE_MAX] = { |
42 | 47 | { &Linear::in, &Linear::in, &Linear::in, &Linear::in }, // Linear is the same for each easing. |
@@ -78,7 +83,11 @@ void Tweener::_bind_methods() { |
78 | 83 | void Tween::_start_tweeners() { |
79 | 84 | if (tweeners.is_empty()) { |
80 | 85 | dead = true; |
81 | | - ERR_FAIL_MSG("Tween without commands, aborting."); |
| 86 | + if (name.length() > 0) { |
| 87 | + ERR_FAIL_MSG(vformat("Tween \"%s\" has no commands, aborting.", name)); |
| 88 | + } else { |
| 89 | + ERR_FAIL_MSG("Tween has no commands, aborting."); |
| 90 | + } |
82 | 91 | } |
83 | 92 |
|
84 | 93 | for (Ref<Tweener> &tweener : tweeners[current_step]) { |
@@ -192,8 +201,14 @@ void Tween::pause() { |
192 | 201 | } |
193 | 202 |
|
194 | 203 | void Tween::play() { |
195 | | - ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree."); |
196 | | - ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state."); |
| 204 | + if (name.length() > 0) { |
| 205 | + ERR_FAIL_COND_MSG(!valid, vformat("Tween \"%s\" invalid. Either finished or created outside scene tree.", name)); |
| 206 | + ERR_FAIL_COND_MSG(dead, vformat("Can't play finished Tween \"%s\", use stop() first to reset its state.", name)); |
| 207 | + } else { |
| 208 | + ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree."); |
| 209 | + ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state."); |
| 210 | + } |
| 211 | + |
197 | 212 | running = true; |
198 | 213 | } |
199 | 214 |
|
@@ -309,7 +324,11 @@ RequiredResult<Tween> Tween::chain() { |
309 | 324 | } |
310 | 325 |
|
311 | 326 | bool Tween::custom_step(double p_delta) { |
312 | | - ERR_FAIL_COND_V_MSG(in_step, true, "Can't call custom_step() during another Tween step."); |
| 327 | + if (name.length() > 0) { |
| 328 | + ERR_FAIL_COND_V_MSG(in_step, true, vformat("Can't call custom_step() during another Tween step for Tween named \"%s\".", name)); |
| 329 | + } else { |
| 330 | + ERR_FAIL_COND_V_MSG(in_step, true, "Can't call custom_step() during another Tween step."); |
| 331 | + } |
313 | 332 |
|
314 | 333 | bool r = running; |
315 | 334 | running = true; |
@@ -341,10 +360,10 @@ bool Tween::step(double p_delta) { |
341 | 360 |
|
342 | 361 | if (!started) { |
343 | 362 | if (tweeners.is_empty()) { |
344 | | - String tween_id; |
| 363 | + String tween_id = name.length() > 0 ? vformat("Tween \"%s\"", name) : "Tween"; |
345 | 364 | Node *node = get_bound_node(); |
346 | 365 | if (node) { |
347 | | - tween_id = vformat("Tween (bound to %s)", node->is_inside_tree() ? (String)node->get_path() : (String)node->get_name()); |
| 366 | + tween_id = vformat("%s (bound to %s)", tween_id, node->is_inside_tree() ? (String)node->get_path() : (String)node->get_name()); |
348 | 367 | } else { |
349 | 368 | tween_id = to_string(); |
350 | 369 | } |
@@ -403,7 +422,11 @@ bool Tween::step(double p_delta) { |
403 | 422 | } else { |
404 | 423 | // Looped twice without using any time, this is 100% certain infinite loop. |
405 | 424 | in_step = false; |
406 | | - ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info."); |
| 425 | + if (name.length() > 0) { |
| 426 | + ERR_FAIL_V_MSG(false, vformat("Infinite loop detected in Tween \"%s\". Check set_loops() description for more info.", name)); |
| 427 | + } else { |
| 428 | + ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info."); |
| 429 | + } |
407 | 430 | } |
408 | 431 | } |
409 | 432 | #endif |
@@ -462,12 +485,23 @@ Variant Tween::interpolate_variant(const Variant &p_initial_val, const Variant & |
462 | 485 | String Tween::_to_string() { |
463 | 486 | String ret = Object::_to_string(); |
464 | 487 | Node *node = get_bound_node(); |
| 488 | + if (name.length() > 0) { |
| 489 | + ret += vformat(" \"%s\"", name); |
| 490 | + } |
465 | 491 | if (node) { |
466 | 492 | ret += vformat(" (bound to %s)", node->get_name()); |
467 | 493 | } |
468 | 494 | return ret; |
469 | 495 | } |
470 | 496 |
|
| 497 | +void Tween::set_name(const StringName &p_name) { |
| 498 | + name = p_name; |
| 499 | +} |
| 500 | + |
| 501 | +StringName Tween::get_name() const { |
| 502 | + return name; |
| 503 | +} |
| 504 | + |
471 | 505 | void Tween::_bind_methods() { |
472 | 506 | ClassDB::bind_method(D_METHOD("tween_property", "object", "property", "final_val", "duration"), &Tween::tween_property); |
473 | 507 | ClassDB::bind_method(D_METHOD("tween_interval", "time"), &Tween::tween_interval); |
@@ -499,6 +533,9 @@ void Tween::_bind_methods() { |
499 | 533 | ClassDB::bind_method(D_METHOD("parallel"), &Tween::parallel); |
500 | 534 | ClassDB::bind_method(D_METHOD("chain"), &Tween::chain); |
501 | 535 |
|
| 536 | + ClassDB::bind_method(D_METHOD("set_name", "name"), &Tween::set_name); |
| 537 | + ClassDB::bind_method(D_METHOD("get_name"), &Tween::get_name); |
| 538 | + |
502 | 539 | ClassDB::bind_static_method("Tween", D_METHOD("interpolate_value", "initial_value", "delta_value", "elapsed_time", "duration", "trans_type", "ease_type"), &Tween::interpolate_variant); |
503 | 540 |
|
504 | 541 | ADD_SIGNAL(MethodInfo("step_finished", PropertyInfo(Variant::INT, "idx"))); |
@@ -546,10 +583,19 @@ double PropertyTweener::_get_custom_interpolated_value(const Variant &p_value) { |
546 | 583 | Variant result; |
547 | 584 | Callable::CallError ce; |
548 | 585 | custom_method.callp(&argptr, 1, result, ce); |
| 586 | + Ref<Tween> tween = _get_tween(); |
549 | 587 | if (ce.error != Callable::CallError::CALL_OK) { |
550 | | - ERR_FAIL_V_MSG(false, "Error calling custom method from PropertyTweener: " + Variant::get_callable_error_text(custom_method, &argptr, 1, ce) + "."); |
| 588 | + if (tween->get_name().length() > 0) { |
| 589 | + ERR_FAIL_V_MSG(false, vformat("Error calling custom method from PropertyTweener in Tween \"%s\": %s.", tween->get_name(), Variant::get_callable_error_text(custom_method, &argptr, 1, ce))); |
| 590 | + } else { |
| 591 | + ERR_FAIL_V_MSG(false, vformat("Error calling custom method from PropertyTweener: %s.", Variant::get_callable_error_text(custom_method, &argptr, 1, ce))); |
| 592 | + } |
551 | 593 | } else if (result.get_type() != Variant::FLOAT) { |
552 | | - ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method. Expected float, got %s.", Variant::get_type_name(result.get_type()))); |
| 594 | + if (tween->get_name().length() > 0) { |
| 595 | + ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method in Tween \"%s\". Expected float, got %s.", tween->get_name(), Variant::get_type_name(result.get_type()))); |
| 596 | + } else { |
| 597 | + ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method. Expected float, got %s.", Variant::get_type_name(result.get_type()))); |
| 598 | + } |
553 | 599 | } |
554 | 600 | return result; |
555 | 601 | } |
@@ -752,7 +798,12 @@ bool CallbackTweener::step(double &r_delta) { |
752 | 798 | Callable::CallError ce; |
753 | 799 | callback.callp(nullptr, 0, result, ce); |
754 | 800 | if (ce.error != Callable::CallError::CALL_OK) { |
755 | | - ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_callable_error_text(callback, nullptr, 0, ce) + "."); |
| 801 | + Ref<Tween> tween = _get_tween(); |
| 802 | + if (tween->get_name().length() > 0) { |
| 803 | + ERR_FAIL_V_MSG(false, vformat("Error calling method from CallbackTweener in Tween \"%s\": %s.", tween->get_name(), Variant::get_callable_error_text(callback, nullptr, 0, ce))); |
| 804 | + } else { |
| 805 | + ERR_FAIL_V_MSG(false, vformat("Error calling method from CallbackTweener: %s.", Variant::get_callable_error_text(callback, nullptr, 0, ce))); |
| 806 | + } |
756 | 807 | } |
757 | 808 |
|
758 | 809 | r_delta = elapsed_time - delay; |
@@ -829,7 +880,11 @@ bool MethodTweener::step(double &r_delta) { |
829 | 880 | Callable::CallError ce; |
830 | 881 | callback.callp(argptr, 1, result, ce); |
831 | 882 | if (ce.error != Callable::CallError::CALL_OK) { |
832 | | - ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_callable_error_text(callback, argptr, 1, ce) + "."); |
| 883 | + if (tween->get_name().length() > 0) { |
| 884 | + ERR_FAIL_V_MSG(false, vformat("Error calling method from MethodTweener in Tween \"%s\": %s.", tween->get_name(), Variant::get_callable_error_text(callback, argptr, 1, ce))); |
| 885 | + } else { |
| 886 | + ERR_FAIL_V_MSG(false, vformat("Error calling method from MethodTweener: %s.", Variant::get_callable_error_text(callback, argptr, 1, ce))); |
| 887 | + } |
833 | 888 | } |
834 | 889 |
|
835 | 890 | if (time < duration) { |
|
0 commit comments