Browse Source

Merge pull request #21047 from gotnospirit/fix_tween_reversed_duration

Tween: Always remove the desired InterpolateData when finished
Rémi Verschelde 7 years ago
parent
commit
a2abe760c8
2 changed files with 40 additions and 26 deletions
  1. 36 25
      scene/animation/tween.cpp
  2. 4 1
      scene/animation/tween.h

+ 36 - 25
scene/animation/tween.cpp

@@ -204,7 +204,7 @@ void Tween::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("resume", "object", "key"), &Tween::resume, DEFVAL(""));
 	ClassDB::bind_method(D_METHOD("resume_all"), &Tween::resume_all);
 	ClassDB::bind_method(D_METHOD("remove", "object", "key"), &Tween::remove, DEFVAL(""));
-	ClassDB::bind_method(D_METHOD("_remove", "object", "key", "first_only"), &Tween::_remove);
+	ClassDB::bind_method(D_METHOD("_remove_by_uid", "uid"), &Tween::_remove_by_uid);
 	ClassDB::bind_method(D_METHOD("remove_all"), &Tween::remove_all);
 	ClassDB::bind_method(D_METHOD("seek", "time"), &Tween::seek);
 	ClassDB::bind_method(D_METHOD("tell"), &Tween::tell);
@@ -615,7 +615,7 @@ void Tween::_tween_process(float p_delta) {
 			emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
 			// not repeat mode, remove completed action
 			if (!repeat)
-				call_deferred("_remove", object, data.concatenated_key, true);
+				call_deferred("_remove_by_uid", data.uid);
 		} else if (!repeat)
 			all_finished = all_finished && data.finish;
 	}
@@ -778,15 +778,9 @@ bool Tween::resume_all() {
 }
 
 bool Tween::remove(Object *p_object, StringName p_key) {
-	_remove(p_object, p_key, false);
-	return true;
-}
-
-void Tween::_remove(Object *p_object, StringName p_key, bool first_only) {
-
 	if (pending_update != 0) {
-		call_deferred("_remove", p_object, p_key, first_only);
-		return;
+		call_deferred("remove", p_object, p_key);
+		return true;
 	}
 	List<List<InterpolateData>::Element *> for_removal;
 	for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -797,14 +791,33 @@ void Tween::_remove(Object *p_object, StringName p_key, bool first_only) {
 			continue;
 		if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
 			for_removal.push_back(E);
-			if (first_only) {
-				break;
-			}
 		}
 	}
 	for (List<List<InterpolateData>::Element *>::Element *E = for_removal.front(); E; E = E->next()) {
 		interpolates.erase(E->get());
 	}
+	return true;
+}
+
+void Tween::_remove_by_uid(int uid) {
+	if (pending_update != 0) {
+		call_deferred("_remove_by_uid", uid);
+		return;
+	}
+
+	for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
+		if (uid == E->get().uid) {
+			E->erase();
+			break;
+		}
+	}
+}
+
+void Tween::_push_interpolate_data(InterpolateData &p_data) {
+	pending_update++;
+	p_data.uid = ++uid;
+	interpolates.push_back(p_data);
+	pending_update--;
 }
 
 bool Tween::remove_all() {
@@ -815,6 +828,7 @@ bool Tween::remove_all() {
 	}
 	set_active(false);
 	interpolates.clear();
+	uid = 0;
 	return true;
 }
 
@@ -1027,7 +1041,7 @@ bool Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
 	if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
 		return false;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1070,7 +1084,7 @@ bool Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_
 	if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
 		return false;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1122,9 +1136,7 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
 	data.arg[3] = p_arg4;
 	data.arg[4] = p_arg5;
 
-	pending_update++;
-	interpolates.push_back(data);
-	pending_update--;
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1175,9 +1187,7 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
 	data.arg[3] = p_arg4;
 	data.arg[4] = p_arg5;
 
-	pending_update++;
-	interpolates.push_back(data);
-	pending_update--;
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1232,7 +1242,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
 	data.ease_type = p_ease_type;
 	data.delay = p_delay;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1283,7 +1293,7 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
 	data.ease_type = p_ease_type;
 	data.delay = p_delay;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1341,7 +1351,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
 	if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
 		return false;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1396,7 +1406,7 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
 	if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
 		return false;
 
-	interpolates.push_back(data);
+	_push_interpolate_data(data);
 	return true;
 }
 
@@ -1407,6 +1417,7 @@ Tween::Tween() {
 	repeat = false;
 	speed_scale = 1;
 	pending_update = 0;
+	uid = 0;
 }
 
 Tween::~Tween() {

+ 4 - 1
scene/animation/tween.h

@@ -100,6 +100,7 @@ private:
 		real_t delay;
 		int args;
 		Variant arg[5];
+		int uid;
 	};
 
 	String autoplay;
@@ -107,6 +108,7 @@ private:
 	bool repeat;
 	float speed_scale;
 	mutable int pending_update;
+	int uid;
 
 	List<InterpolateData> interpolates;
 
@@ -131,7 +133,8 @@ private:
 	bool _apply_tween_value(InterpolateData &p_data, Variant &value);
 
 	void _tween_process(float p_delta);
-	void _remove(Object *p_object, StringName p_key, bool first_only);
+	void _remove_by_uid(int uid);
+	void _push_interpolate_data(InterpolateData &p_data);
 
 protected:
 	bool _set(const StringName &p_name, const Variant &p_value);