diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 4fa78cf5712..4fe3b70da4e 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -57,6 +57,11 @@ void Tweener::set_tween(const Ref &p_tween) { tween_id = p_tween->get_instance_id(); } +void Tweener::start() { + elapsed_time = 0; + finished = false; +} + Ref Tweener::_get_tween() { return Ref(ObjectDB::get_instance(tween_id)); } @@ -121,7 +126,8 @@ Ref Tween::tween_property(const Object *p_target, const NodePat return nullptr; } - Ref tweener = memnew(PropertyTweener(p_target, property_subnames, p_to, p_duration)); + Ref tweener; + tweener.instantiate(p_target, property_subnames, p_to, p_duration); append(tweener); return tweener; } @@ -129,7 +135,8 @@ Ref Tween::tween_property(const Object *p_target, const NodePat Ref Tween::tween_interval(double p_time) { CHECK_VALID(); - Ref tweener = memnew(IntervalTweener(p_time)); + Ref tweener; + tweener.instantiate(p_time); append(tweener); return tweener; } @@ -137,7 +144,8 @@ Ref Tween::tween_interval(double p_time) { Ref Tween::tween_callback(const Callable &p_callback) { CHECK_VALID(); - Ref tweener = memnew(CallbackTweener(p_callback)); + Ref tweener; + tweener.instantiate(p_callback); append(tweener); return tweener; } @@ -149,7 +157,8 @@ Ref Tween::tween_method(const Callable &p_callback, const Variant return nullptr; } - Ref tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration)); + Ref tweener; + tweener.instantiate(p_callback, p_from, p_to, p_duration); append(tweener); return tweener; } @@ -232,7 +241,7 @@ Ref Tween::set_process_mode(TweenProcessMode p_mode) { return this; } -Tween::TweenProcessMode Tween::get_process_mode() { +Tween::TweenProcessMode Tween::get_process_mode() const { return process_mode; } @@ -241,7 +250,7 @@ Ref Tween::set_pause_mode(TweenPauseMode p_mode) { return this; } -Tween::TweenPauseMode Tween::get_pause_mode() { +Tween::TweenPauseMode Tween::get_pause_mode() const { return pause_mode; } @@ -283,7 +292,7 @@ Ref Tween::set_trans(TransitionType p_trans) { return this; } -Tween::TransitionType Tween::get_trans() { +Tween::TransitionType Tween::get_trans() const { return default_transition; } @@ -292,7 +301,7 @@ Ref Tween::set_ease(EaseType p_ease) { return this; } -Tween::EaseType Tween::get_ease() { +Tween::EaseType Tween::get_ease() const { return default_ease; } @@ -528,10 +537,6 @@ Tween::Tween() { ERR_FAIL_MSG("Tween can't be created directly. Use create_tween() method."); } -Tween::Tween(bool p_valid) { - valid = p_valid; -} - Tween::Tween(SceneTree *p_parent_tree) { parent_tree = p_parent_tree; valid = true; @@ -582,8 +587,7 @@ Ref PropertyTweener::set_delay(double p_delay) { } void PropertyTweener::start() { - elapsed_time = 0; - finished = false; + Tweener::start(); Object *target_instance = ObjectDB::get_instance(target); if (!target_instance) { @@ -696,11 +700,6 @@ PropertyTweener::PropertyTweener() { ERR_FAIL_MSG("PropertyTweener can't be created directly. Use the tween_property() method in Tween."); } -void IntervalTweener::start() { - elapsed_time = 0; - finished = false; -} - bool IntervalTweener::step(double &r_delta) { if (finished) { return false; @@ -731,11 +730,6 @@ Ref CallbackTweener::set_delay(double p_delay) { return this; } -void CallbackTweener::start() { - elapsed_time = 0; - finished = false; -} - bool CallbackTweener::step(double &r_delta) { if (finished) { return false; @@ -796,11 +790,6 @@ Ref MethodTweener::set_ease(Tween::EaseType p_ease) { return this; } -void MethodTweener::start() { - elapsed_time = 0; - finished = false; -} - bool MethodTweener::step(double &r_delta) { if (finished) { return false; @@ -881,8 +870,7 @@ MethodTweener::MethodTweener() { } void SubtweenTweener::start() { - elapsed_time = 0; - finished = false; + Tweener::start(); // Reset the subtween. subtween->stop(); diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 793a5aa4b4b..8d63746725c 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -44,7 +44,7 @@ class Tweener : public RefCounted { public: virtual void set_tween(const Ref &p_tween); - virtual void start() = 0; + virtual void start(); virtual bool step(double &r_delta) = 0; protected: @@ -163,9 +163,9 @@ public: Ref bind_node(const Node *p_node); Ref set_process_mode(TweenProcessMode p_mode); - TweenProcessMode get_process_mode(); + TweenProcessMode get_process_mode() const; Ref set_pause_mode(TweenPauseMode p_mode); - TweenPauseMode get_pause_mode(); + TweenPauseMode get_pause_mode() const; Ref set_ignore_time_scale(bool p_ignore = true); bool is_ignoring_time_scale() const; @@ -174,9 +174,9 @@ public: int get_loops_left() const; Ref set_speed_scale(float p_speed); Ref set_trans(TransitionType p_trans); - TransitionType get_trans(); + TransitionType get_trans() const; Ref set_ease(EaseType p_ease); - EaseType get_ease(); + EaseType get_ease() const; Ref parallel(); Ref chain(); @@ -190,7 +190,6 @@ public: double get_total_time() const; Tween(); - Tween(bool p_valid); Tween(SceneTree *p_parent_tree); }; @@ -246,7 +245,6 @@ class IntervalTweener : public Tweener { GDCLASS(IntervalTweener, Tweener); public: - void start() override; bool step(double &r_delta) override; IntervalTweener(double p_time); @@ -262,7 +260,6 @@ class CallbackTweener : public Tweener { public: Ref set_delay(double p_delay); - void start() override; bool step(double &r_delta) override; CallbackTweener(const Callable &p_callback); @@ -287,7 +284,6 @@ public: Ref set_delay(double p_delay); void set_tween(const Ref &p_tween) override; - void start() override; bool step(double &r_delta) override; MethodTweener(const Callable &p_callback, const Variant &p_from, const Variant &p_to, double p_duration); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index a48885b77da..9df2bf17d8a 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -644,32 +644,31 @@ bool SceneTree::process(double p_time) { void SceneTree::process_timers(double p_delta, bool p_physics_frame) { _THREAD_SAFE_METHOD_ - List>::Element *L = timers.back(); //last element + const List>::Element *L = timers.back(); // Last element. + const double unscaled_delta = Engine::get_singleton()->get_process_step(); for (List>::Element *E = timers.front(); E;) { List>::Element *N = E->next(); - if ((paused && !E->get()->is_process_always()) || (E->get()->is_process_in_physics() != p_physics_frame)) { + Ref timer = E->get(); + + if ((paused && !timer->is_process_always()) || (timer->is_process_in_physics() != p_physics_frame)) { if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. + break; // Break on last, so if new timers were added during list traversal, ignore them. } E = N; continue; } - double time_left = E->get()->get_time_left(); - if (E->get()->is_ignoring_time_scale()) { - time_left -= Engine::get_singleton()->get_process_step(); - } else { - time_left -= p_delta; - } - E->get()->set_time_left(time_left); + double time_left = timer->get_time_left(); + time_left -= timer->is_ignoring_time_scale() ? unscaled_delta : p_delta; + timer->set_time_left(time_left); if (time_left <= 0) { E->get()->emit_signal(SNAME("timeout")); timers.erase(E); } if (E == L) { - break; //break on last, so if new timers were added during list traversal, ignore them. + break; // Break on last, so if new timers were added during list traversal, ignore them. } E = N; } @@ -678,12 +677,15 @@ void SceneTree::process_timers(double p_delta, bool p_physics_frame) { void SceneTree::process_tweens(double p_delta, bool p_physics) { _THREAD_SAFE_METHOD_ // This methods works similarly to how SceneTreeTimers are handled. - List>::Element *L = tweens.back(); + const List>::Element *L = tweens.back(); + const double unscaled_delta = Engine::get_singleton()->get_process_step(); for (List>::Element *E = tweens.front(); E;) { List>::Element *N = E->next(); + Ref &tween = E->get(); + // Don't process if paused or process mode doesn't match. - if (!E->get()->can_process(paused) || (p_physics == (E->get()->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) { + if (!tween->can_process(paused) || (p_physics == (tween->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) { if (E == L) { break; } @@ -691,9 +693,8 @@ void SceneTree::process_tweens(double p_delta, bool p_physics) { continue; } - double time_step = E->get()->is_ignoring_time_scale() ? Engine::get_singleton()->get_process_step() : p_delta; - if (!E->get()->step(time_step)) { - E->get()->clear(); + if (!tween->step(tween->is_ignoring_time_scale() ? unscaled_delta : p_delta)) { + tween->clear(); tweens.erase(E); } if (E == L) { @@ -1589,9 +1590,14 @@ Ref SceneTree::create_tween() { return tween; } -bool SceneTree::remove_tween(const Ref &p_tween) { +void SceneTree::remove_tween(const Ref &p_tween) { _THREAD_SAFE_METHOD_ - return tweens.erase(p_tween); + for (List>::Element *E = tweens.back(); E; E = E->prev()) { + if (E->get() == p_tween) { + E->erase(); + break; + } + } } TypedArray SceneTree::get_processed_tweens() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 8d1d53917a4..2cfa1885b53 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -411,7 +411,7 @@ public: Ref create_timer(double p_delay_sec, bool p_process_always = true, bool p_process_in_physics = false, bool p_ignore_time_scale = false); Ref create_tween(); - bool remove_tween(const Ref &p_tween); + void remove_tween(const Ref &p_tween); TypedArray get_processed_tweens(); //used by Main::start, don't use otherwise