summaryrefslogtreecommitdiff
path: root/scene/animation/tween.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/tween.cpp')
-rw-r--r--scene/animation/tween.cpp197
1 files changed, 124 insertions, 73 deletions
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index d94cbfa08c..854db5fee2 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -42,50 +42,61 @@ void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const
// Determine command argument count
int &count = cmd.args;
- if (p_arg10.get_type() != Variant::NIL)
+ if (p_arg10.get_type() != Variant::NIL) {
count = 10;
- else if (p_arg9.get_type() != Variant::NIL)
+ } else if (p_arg9.get_type() != Variant::NIL) {
count = 9;
- else if (p_arg8.get_type() != Variant::NIL)
+ } else if (p_arg8.get_type() != Variant::NIL) {
count = 8;
- else if (p_arg7.get_type() != Variant::NIL)
+ } else if (p_arg7.get_type() != Variant::NIL) {
count = 7;
- else if (p_arg6.get_type() != Variant::NIL)
+ } else if (p_arg6.get_type() != Variant::NIL) {
count = 6;
- else if (p_arg5.get_type() != Variant::NIL)
+ } else if (p_arg5.get_type() != Variant::NIL) {
count = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
count = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
count = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
count = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
count = 1;
- else
+ } else {
count = 0;
+ }
// Add the specified arguments to the command
- if (count > 0)
+ if (count > 0) {
cmd.arg[0] = p_arg1;
- if (count > 1)
+ }
+ if (count > 1) {
cmd.arg[1] = p_arg2;
- if (count > 2)
+ }
+ if (count > 2) {
cmd.arg[2] = p_arg3;
- if (count > 3)
+ }
+ if (count > 3) {
cmd.arg[3] = p_arg4;
- if (count > 4)
+ }
+ if (count > 4) {
cmd.arg[4] = p_arg5;
- if (count > 5)
+ }
+ if (count > 5) {
cmd.arg[5] = p_arg6;
- if (count > 6)
+ }
+ if (count > 6) {
cmd.arg[6] = p_arg7;
- if (count > 7)
+ }
+ if (count > 7) {
cmd.arg[7] = p_arg8;
- if (count > 8)
+ }
+ if (count > 8) {
cmd.arg[8] = p_arg9;
- if (count > 9)
+ }
+ if (count > 9) {
cmd.arg[9] = p_arg10;
+ }
}
void Tween::_process_pending_commands() {
@@ -179,26 +190,30 @@ void Tween::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
// Are we processing during physics time?
- if (tween_process_mode == TWEEN_PROCESS_PHYSICS)
+ if (tween_process_mode == TWEEN_PROCESS_PHYSICS) {
// Do nothing since we aren't aligned with physics when we should be
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_process_delta_time());
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Are we processing during 'regular' time?
- if (tween_process_mode == TWEEN_PROCESS_IDLE)
+ if (tween_process_mode == TWEEN_PROCESS_IDLE) {
// Do nothing since we would only process during idle time
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_physics_process_delta_time());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -346,8 +361,9 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT)
+ if (final_val.get_type() == Variant::INT) {
final_val = final_val.operator real_t();
+ }
return final_val;
}
@@ -388,8 +404,9 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT)
+ if (final_val.get_type() == Variant::INT) {
final_val = final_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(p_data.initial_val, final_val, p_data.delta_val);
@@ -403,8 +420,9 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (initial_val.get_type() == Variant::INT)
+ if (initial_val.get_type() == Variant::INT) {
initial_val = initial_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(initial_val, p_data.final_val, p_data.delta_val);
@@ -652,8 +670,9 @@ void Tween::_tween_process(float p_delta) {
_process_pending_commands();
// If the scale is 0, make no progress on the tweens
- if (speed_scale == 0)
+ if (speed_scale == 0) {
return;
+ }
// Update the delta and whether we are pending an update
p_delta *= speed_scale;
@@ -676,8 +695,9 @@ void Tween::_tween_process(float p_delta) {
}
// If we are all finished, we can reset all of the tweens
- if (repeats_finished)
+ if (repeats_finished) {
reset_all();
+ }
}
// Are all of the tweens complete?
@@ -692,20 +712,22 @@ void Tween::_tween_process(float p_delta) {
all_finished = all_finished && data.finish;
// Is the data not active or already finished? No need to go any further
- if (!data.active || data.finish)
+ if (!data.active || data.finish) {
continue;
+ }
// Get the target object for this interpolation
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Are we still delaying this tween?
bool prev_delaying = data.elapsed <= data.delay;
data.elapsed += p_delta;
- if (data.elapsed < data.delay)
+ if (data.elapsed < data.delay) {
continue;
- else if (prev_delaying) {
+ } else if (prev_delaying) {
// We can apply the tween's value to the data and emit that the tween has started
_apply_tween_value(data, data.initial_val);
emit_signal("tween_started", object, NodePath(Vector<StringName>(), data.key, false));
@@ -778,8 +800,9 @@ void Tween::_tween_process(float p_delta) {
emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
// If we are not repeating the tween, remove it
- if (!repeat)
+ if (!repeat) {
call_deferred("_remove_by_uid", data.uid);
+ }
} else if (!repeat) {
// Check whether all tweens are finished
all_finished = all_finished && data.finish;
@@ -809,8 +832,9 @@ bool Tween::is_active() const {
void Tween::set_active(bool p_active) {
// Do nothing if it's the same active mode that we currently are
- if (is_active() == p_active)
+ if (is_active() == p_active) {
return;
+ }
// Depending on physics or idle, set processing
switch (tween_process_mode) {
@@ -860,8 +884,9 @@ void Tween::reset(Object *p_object, StringName p_key) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Do we have the correct object and key?
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -870,8 +895,9 @@ void Tween::reset(Object *p_object, StringName p_key) {
data.finish = false;
// Also apply the initial state if there isn't a delay
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
}
pending_update--;
@@ -887,8 +913,9 @@ void Tween::reset_all() {
data.finish = false;
// If there isn't a delay, apply the value to the object
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
pending_update--;
}
@@ -900,13 +927,15 @@ void Tween::stop(Object *p_object, StringName p_key) {
// Get the object the tween is targeting
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Is this the correct object and does it have the given key?
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
// Disable the tween
data.active = false;
+ }
}
pending_update--;
}
@@ -936,12 +965,14 @@ void Tween::resume(Object *p_object, StringName p_key) {
// Grab the object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// If the object and string key match, activate it
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
data.active = true;
+ }
}
pending_update--;
}
@@ -974,8 +1005,9 @@ void Tween::remove(Object *p_object, StringName p_key) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// If the target object and string key match, queue it for removal
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -1076,9 +1108,10 @@ real_t Tween::tell() const {
for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
// Get the data and figure out if it's position is further along than the previous ones
const InterpolateData &data = E->get();
- if (data.elapsed > pos)
+ if (data.elapsed > pos) {
// Save it if so
pos = data.elapsed;
+ }
}
pending_update--;
return pos;
@@ -1098,9 +1131,10 @@ real_t Tween::get_runtime() const {
// Get the tween data and see if it's runtime is greater than the previous tweens
const InterpolateData &data = E->get();
real_t t = data.delay + data.duration;
- if (t > runtime)
+ if (t > runtime) {
// This is the longest running tween
runtime = t;
+ }
}
pending_update--;
@@ -1305,8 +1339,9 @@ void Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
}
// Is there not a valid delta?
- if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
+ if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val)) {
return;
+ }
// Add this interpolation to the total
_push_interpolate_data(data);
@@ -1324,14 +1359,17 @@ void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
// If no initial value given, grab the initial value from the object
// TODO: Is this documented? This is very useful and removes a lot of clutter from tweens!
- if (p_initial_val.get_type() == Variant::NIL)
+ if (p_initial_val.get_type() == Variant::NIL) {
p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
// Convert any integers into REALs as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT)
+ if (p_initial_val.get_type() == Variant::INT) {
p_initial_val = p_initial_val.operator real_t();
- if (p_final_val.get_type() == Variant::INT)
+ }
+ if (p_final_val.get_type() == Variant::INT) {
p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
_build_interpolation(INTER_PROPERTY, p_object, &p_property, nullptr, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
@@ -1345,10 +1383,12 @@ void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_
}
// Convert any integers into REALs as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT)
+ if (p_initial_val.get_type() == Variant::INT) {
p_initial_val = p_initial_val.operator real_t();
- if (p_final_val.get_type() == Variant::INT)
+ }
+ if (p_final_val.get_type() == Variant::INT) {
p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
_build_interpolation(INTER_METHOD, p_object, nullptr, &p_method, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
@@ -1387,18 +1427,19 @@ void Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
// Add arguments to the interpolation
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1444,18 +1485,19 @@ void Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
// Collect arguments for the callback
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1481,12 +1523,14 @@ void Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
// If no initial value is given, grab it from the source object
// TODO: Is this documented? It's really helpful for decluttering tweens
- if (p_initial_val.get_type() == Variant::NIL)
+ if (p_initial_val.get_type() == Variant::NIL) {
p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
// Convert initial INT values to FLOAT as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT)
+ if (p_initial_val.get_type() == Variant::INT) {
p_initial_val = p_initial_val.operator real_t();
+ }
// Confirm the source and target objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1512,8 +1556,9 @@ void Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
ERR_FAIL_COND(!target_prop_valid);
// Convert target INT to FLOAT since it is better for interpolation
- if (target_val.get_type() == Variant::INT)
+ if (target_val.get_type() == Variant::INT) {
target_val = target_val.operator real_t();
+ }
// Verify that the target value and initial value are the same type
ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
@@ -1548,8 +1593,9 @@ void Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
return;
}
// Convert initial INT values to FLOAT as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT)
+ if (p_initial_val.get_type() == Variant::INT) {
p_initial_val = p_initial_val.operator real_t();
+ }
// Verify the source and target objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1575,8 +1621,9 @@ void Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
// Convert target INT values to FLOAT as they are better for interpolation
- if (target_val.get_type() == Variant::INT)
+ if (target_val.get_type() == Variant::INT) {
target_val = target_val.operator real_t();
+ }
ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
// Make the new InterpolateData for the method follow
@@ -1613,8 +1660,9 @@ void Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
p_initial_property = p_initial_property.get_as_property_path();
// Convert the initial INT values to FLOAT as they are better for Interpolation
- if (p_final_val.get_type() == Variant::INT)
+ if (p_final_val.get_type() == Variant::INT) {
p_final_val = p_final_val.operator real_t();
+ }
// Verify both objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1640,8 +1688,9 @@ void Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
ERR_FAIL_COND(!initial_prop_valid);
// Convert the initial INT value to FLOAT as it is better for interpolation
- if (initial_val.get_type() == Variant::INT)
+ if (initial_val.get_type() == Variant::INT) {
initial_val = initial_val.operator real_t();
+ }
ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the InterpolateData object
@@ -1681,8 +1730,9 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
}
// Convert final INT values to FLOAT as they are better for interpolation
- if (p_final_val.get_type() == Variant::INT)
+ if (p_final_val.get_type() == Variant::INT) {
p_final_val = p_final_val.operator real_t();
+ }
// Make sure the given objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1708,8 +1758,9 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
// Convert initial INT values to FLOAT as they aer better for interpolation
- if (initial_val.get_type() == Variant::INT)
+ if (initial_val.get_type() == Variant::INT) {
initial_val = initial_val.operator real_t();
+ }
ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the new InterpolateData object