Browse Source

Merge pull request #51237 from KoBeWi/tween_fix()

Various fixes to Tween code
Rémi Verschelde 4 years ago
parent
commit
195ea41a7a
3 changed files with 28 additions and 15 deletions
  1. 23 12
      scene/animation/tween.cpp
  2. 4 2
      scene/animation/tween.h
  3. 1 1
      scene/main/scene_tree.cpp

+ 23 - 12
scene/animation/tween.cpp

@@ -36,6 +36,10 @@ void Tweener::set_tween(Ref<Tween> p_tween) {
 	tween = p_tween;
 }
 
+void Tweener::clear_tween() {
+	tween.unref();
+}
+
 void Tweener::_bind_methods() {
 	ADD_SIGNAL(MethodInfo("finished"));
 }
@@ -53,7 +57,7 @@ void Tween::start_tweeners() {
 
 Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration) {
 	ERR_FAIL_NULL_V(p_target, nullptr);
-	ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+	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.");
 
 	Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration));
@@ -62,7 +66,7 @@ Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property
 }
 
 Ref<IntervalTweener> Tween::tween_interval(float p_time) {
-	ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+	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.");
 
 	Ref<IntervalTweener> tweener = memnew(IntervalTweener(p_time));
@@ -71,7 +75,7 @@ Ref<IntervalTweener> Tween::tween_interval(float p_time) {
 }
 
 Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
-	ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+	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.");
 
 	Ref<CallbackTweener> tweener = memnew(CallbackTweener(p_callback));
@@ -80,7 +84,7 @@ Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
 }
 
 Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float p_to, float p_duration) {
-	ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+	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.");
 
 	Ref<MethodTweener> tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration));
@@ -88,9 +92,7 @@ Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float
 	return tweener;
 }
 
-Ref<Tween> Tween::append(Ref<Tweener> p_tweener) {
-	ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
-	ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
+void Tween::append(Ref<Tweener> p_tweener) {
 	p_tweener->set_tween(this);
 
 	if (parallel_enabled) {
@@ -102,8 +104,6 @@ Ref<Tween> Tween::append(Ref<Tweener> p_tweener) {
 
 	tweeners.resize(current_step + 1);
 	tweeners.write[current_step].push_back(p_tweener);
-
-	return this;
 }
 
 void Tween::stop() {
@@ -117,7 +117,7 @@ void Tween::pause() {
 }
 
 void Tween::play() {
-	ERR_FAIL_COND_MSG(invalid, "Tween invalid, can't play.");
+	ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree.");
 	ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state.");
 	running = true;
 }
@@ -132,11 +132,22 @@ bool Tween::is_running() {
 }
 
 void Tween::set_valid(bool p_valid) {
-	invalid = !p_valid;
+	valid = p_valid;
 }
 
 bool Tween::is_valid() {
-	return invalid;
+	return valid;
+}
+
+void Tween::clear() {
+	valid = false;
+
+	for (List<Ref<Tweener>> &step : tweeners) {
+		for (Ref<Tweener> &tweener : step) {
+			tweener->clear_tween();
+		}
+	}
+	tweeners.clear();
 }
 
 Ref<Tween> Tween::bind_node(Node *p_node) {

+ 4 - 2
scene/animation/tween.h

@@ -43,6 +43,7 @@ public:
 	virtual void set_tween(Ref<Tween> p_tween);
 	virtual void start() = 0;
 	virtual bool step(float &r_delta) = 0;
+	void clear_tween();
 
 protected:
 	static void _bind_methods();
@@ -111,7 +112,7 @@ private:
 	bool started = false;
 	bool running = true;
 	bool dead = false;
-	bool invalid = true;
+	bool valid = false;
 	bool default_parallel = false;
 	bool parallel_enabled = false;
 
@@ -128,7 +129,7 @@ public:
 	Ref<IntervalTweener> tween_interval(float p_time);
 	Ref<CallbackTweener> tween_callback(Callable p_callback);
 	Ref<MethodTweener> tween_method(Callable p_callback, float p_from, float p_to, float p_duration);
-	Ref<Tween> append(Ref<Tweener> p_tweener);
+	void append(Ref<Tweener> p_tweener);
 
 	bool custom_step(float p_delta);
 	void stop();
@@ -139,6 +140,7 @@ public:
 	bool is_running();
 	void set_valid(bool p_valid);
 	bool is_valid();
+	void clear();
 
 	Ref<Tween> bind_node(Node *p_node);
 	Ref<Tween> set_process_mode(TweenProcessMode p_mode);

+ 1 - 1
scene/main/scene_tree.cpp

@@ -544,7 +544,7 @@ void SceneTree::process_tweens(float p_delta, bool p_physics) {
 		}
 
 		if (!E->get()->step(p_delta)) {
-			E->get()->set_valid(false);
+			E->get()->clear();
 			tweens.erase(E);
 		}
 		if (E == L) {