From 64f77aa8f365e0be713a06d940f9a2ec912553e3 Mon Sep 17 00:00:00 2001 From: sanikoyes Date: Fri, 19 Dec 2014 17:13:20 +0800 Subject: [PATCH] 1.Change interpolate_callback:p_times_in_sec argument before p_callback argument(more readable) 2.NodePath replace to instance_ID(can control object doe's not in scene tree) 3.Change interpolate types from Node to Object, can control more types(etc script class object) 4.Add pending_update counter, avoid insert/remove interpolates-list while traversal it --- demos/misc/tween/main.gd | 4 +- scene/animation/tween.cpp | 195 +++++++++++++++++++++++--------------- scene/animation/tween.h | 45 +++++---- 3 files changed, 146 insertions(+), 98 deletions(-) diff --git a/demos/misc/tween/main.gd b/demos/misc/tween/main.gd index 364651c827f..a0106a7682f 100644 --- a/demos/misc/tween/main.gd +++ b/demos/misc/tween/main.gd @@ -112,8 +112,8 @@ func reset_tween(): tween.interpolate_property(sprite, "transform/rot", 360, 0, 2, state.trans, state.eases, 2) if get_node("modes/callback").is_pressed(): - tween.interpolate_callback(self, "on_callback", 0.5, "0.5 second's after") - tween.interpolate_callback(self, "on_callback", 1.2, "1.2 second's after") + tween.interpolate_callback(self, 0.5, "on_callback", "0.5 second's after") + tween.interpolate_callback(self, 0.2, "on_callback", "1.2 second's after") if get_node("modes/follow").is_pressed(): follow.show() diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 59793815f50..f668e525904 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -124,32 +124,34 @@ void Tween::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_tween_process_mode"),&Tween::get_tween_process_mode); ObjectTypeDB::bind_method(_MD("start"),&Tween::start ); - ObjectTypeDB::bind_method(_MD("reset","node","key"),&Tween::reset ); + ObjectTypeDB::bind_method(_MD("reset","object","key"),&Tween::reset ); ObjectTypeDB::bind_method(_MD("reset_all"),&Tween::reset_all ); - ObjectTypeDB::bind_method(_MD("stop","node","key"),&Tween::stop ); + ObjectTypeDB::bind_method(_MD("stop","object","key"),&Tween::stop ); ObjectTypeDB::bind_method(_MD("stop_all"),&Tween::stop_all ); - ObjectTypeDB::bind_method(_MD("resume","node","key"),&Tween::resume ); + ObjectTypeDB::bind_method(_MD("resume","object","key"),&Tween::resume ); ObjectTypeDB::bind_method(_MD("resume_all"),&Tween::resume_all ); - ObjectTypeDB::bind_method(_MD("remove","node","key"),&Tween::remove ); + ObjectTypeDB::bind_method(_MD("remove","object","key"),&Tween::remove ); ObjectTypeDB::bind_method(_MD("remove_all"),&Tween::remove_all ); ObjectTypeDB::bind_method(_MD("seek","time"),&Tween::seek ); ObjectTypeDB::bind_method(_MD("tell"),&Tween::tell ); ObjectTypeDB::bind_method(_MD("get_runtime"),&Tween::get_runtime ); - ObjectTypeDB::bind_method(_MD("interpolate_property","node","property","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_property, DEFVAL(0) ); - ObjectTypeDB::bind_method(_MD("interpolate_method","node","method","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_method, DEFVAL(0) ); - ObjectTypeDB::bind_method(_MD("interpolate_callback","node","callback","times_in_sec","args"),&Tween::interpolate_callback, DEFVAL(Variant()) ); - ObjectTypeDB::bind_method(_MD("follow_property","node","property","initial_val","target","target_property","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_property, DEFVAL(0) ); - ObjectTypeDB::bind_method(_MD("follow_method","node","method","initial_val","target","target_method","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_method, DEFVAL(0) ); - ObjectTypeDB::bind_method(_MD("targeting_property","node","property","initial","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_property, DEFVAL(0) ); - ObjectTypeDB::bind_method(_MD("targeting_method","node","method","initial","initial_method","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_method, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("interpolate_property","object","property","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_property, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("interpolate_method","object","method","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::interpolate_method, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("interpolate_callback","object","times_in_sec","callback","args"),&Tween::interpolate_callback, DEFVAL(Variant()) ); + ObjectTypeDB::bind_method(_MD("follow_property","object","property","initial_val","target","target_property","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_property, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("follow_method","object","method","initial_val","target","target_method","times_in_sec","trans_type","ease_type","delay"),&Tween::follow_method, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("targeting_property","object","property","initial","initial_val","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_property, DEFVAL(0) ); + ObjectTypeDB::bind_method(_MD("targeting_method","object","method","initial","initial_method","final_val","times_in_sec","trans_type","ease_type","delay"),&Tween::targeting_method, DEFVAL(0) ); - ADD_SIGNAL( MethodInfo("tween_start", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key")) ); - ADD_SIGNAL( MethodInfo("tween_step", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key"), PropertyInfo( Variant::REAL,"elapsed"), PropertyInfo( Variant::OBJECT,"value")) ); - ADD_SIGNAL( MethodInfo("tween_complete", PropertyInfo( Variant::OBJECT,"node"), PropertyInfo( Variant::STRING,"key")) ); + ADD_SIGNAL( MethodInfo("tween_start", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key")) ); + ADD_SIGNAL( MethodInfo("tween_step", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key"), PropertyInfo( Variant::REAL,"elapsed"), PropertyInfo( Variant::OBJECT,"value")) ); + ADD_SIGNAL( MethodInfo("tween_complete", PropertyInfo( Variant::OBJECT,"object"), PropertyInfo( Variant::STRING,"key")) ); ADD_PROPERTY( PropertyInfo( Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_tween_process_mode"), _SCS("get_tween_process_mode")); - //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "activate"), _SCS("set_active"), _SCS("is_active")); + + BIND_CONSTANT(TWEEN_PROCESS_FIXED); + BIND_CONSTANT(TWEEN_PROCESS_IDLE); BIND_CONSTANT(TRANS_LINEAR); BIND_CONSTANT(TRANS_SINE); @@ -181,19 +183,19 @@ Variant& Tween::_get_initial_val(InterpolateData& p_data) { case TARGETING_PROPERTY: case TARGETING_METHOD: { - Node *node = get_node(p_data.target); - ERR_FAIL_COND_V(node == NULL,p_data.initial_val); + Object *object = ObjectDB::get_instance(p_data.target_id); + ERR_FAIL_COND_V(object == NULL,p_data.initial_val); static Variant initial_val; if(p_data.type == TARGETING_PROPERTY) { bool valid = false; - initial_val = node->get(p_data.target_key, &valid); + initial_val = object->get(p_data.target_key, &valid); ERR_FAIL_COND_V(!valid,p_data.initial_val); } else { Variant::CallError error; - initial_val = node->call(p_data.target_key, NULL, 0, error); + initial_val = object->call(p_data.target_key, NULL, 0, error); ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK,p_data.initial_val); } return initial_val; @@ -213,7 +215,7 @@ Variant& Tween::_get_delta_val(InterpolateData& p_data) { case FOLLOW_PROPERTY: case FOLLOW_METHOD: { - Node *target = get_node(p_data.target); + Object *target = ObjectDB::get_instance(p_data.target_id); ERR_FAIL_COND_V(target == NULL,p_data.initial_val); Variant final_val; @@ -264,6 +266,11 @@ Variant Tween::_run_equation(InterpolateData& p_data) { switch(initial_val.get_type()) { + + case Variant::BOOL: + result = ((int) _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int) initial_val, (int) delta_val, p_data.times_in_sec)) >= 0.5; + break; + case Variant::INT: result = (int) _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int) initial_val, (int) delta_val, p_data.times_in_sec); break; @@ -409,7 +416,7 @@ Variant Tween::_run_equation(InterpolateData& p_data) { bool Tween::_apply_tween_value(InterpolateData& p_data, Variant& value) { - Object *object = get_node(p_data.path); + Object *object = ObjectDB::get_instance(p_data.id); ERR_FAIL_COND_V(object == NULL, false); switch(p_data.type) { @@ -452,6 +459,7 @@ void Tween::_tween_process(float p_delta) { return; p_delta *= speed_scale; + pending_update ++; // if repeat and all interpolates was finished then reset all interpolates if(repeat) { bool all_finished = true; @@ -476,7 +484,7 @@ void Tween::_tween_process(float p_delta) { if(!data.active || data.finish) continue; - Object *object = get_node(data.path); + Object *object = ObjectDB::get_instance(data.id); if(object == NULL) continue; @@ -523,6 +531,7 @@ void Tween::_tween_process(float p_delta) { if(data.finish) emit_signal("tween_complete",object,data.key); } + pending_update --; } void Tween::set_tween_process_mode(TweenProcessMode p_mode) { @@ -598,16 +607,17 @@ bool Tween::start() { return true; } -bool Tween::reset(Node *p_node, String p_key) { +bool Tween::reset(Object *p_object, String p_key) { + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); - Node *node = get_node(data.path); - if(node == NULL) + Object *object = ObjectDB::get_instance(data.id); + if(object == NULL) continue; - if(node == p_node && data.key == p_key) { + if(object == p_object && data.key == p_key) { data.elapsed = 0; data.finish = false; @@ -615,11 +625,13 @@ bool Tween::reset(Node *p_node, String p_key) { _apply_tween_value(data, data.initial_val); } } + pending_update --; return true; } bool Tween::reset_all() { + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); @@ -628,20 +640,23 @@ bool Tween::reset_all() { if(data.delay == 0) _apply_tween_value(data, data.initial_val); } + pending_update --; return true; } -bool Tween::stop(Node *p_node, String p_key) { +bool Tween::stop(Object *p_object, String p_key) { + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); - Node *node = get_node(data.path); - if(node == NULL) + Object *object = ObjectDB::get_instance(data.id); + if(object == NULL) continue; - if(node == p_node && data.key == p_key) + if(object == p_object && data.key == p_key) data.active = false; } + pending_update --; return true; } @@ -650,28 +665,32 @@ bool Tween::stop_all() { set_active(false); _set_process(false); + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); data.active = false; } + pending_update --; return true; } -bool Tween::resume(Node *p_node, String p_key) { +bool Tween::resume(Object *p_object, String p_key) { set_active(true); _set_process(true); + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); - Node *node = get_node(data.path); - if(node == NULL) + Object *object = ObjectDB::get_instance(data.id); + if(object == NULL) continue; - if(node == p_node && data.key == p_key) + if(object == p_object && data.key == p_key) data.active = true; } + pending_update --; return true; } @@ -680,23 +699,26 @@ bool Tween::resume_all() { set_active(true); _set_process(true); + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); data.active = true; } + pending_update --; return true; } -bool Tween::remove(Node *p_node, String p_key) { +bool Tween::remove(Object *p_object, String p_key) { + ERR_FAIL_COND_V(pending_update != 0, false); for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); - Node *node = get_node(data.path); - if(node == NULL) + Object *object = ObjectDB::get_instance(data.id); + if(object == NULL) continue; - if(node == p_node && data.key == p_key) { + if(object == p_object && data.key == p_key) { interpolates.erase(E); return true; } @@ -706,6 +728,7 @@ bool Tween::remove(Node *p_node, String p_key) { bool Tween::remove_all() { + ERR_FAIL_COND_V(pending_update != 0, false); set_active(false); _set_process(false); interpolates.clear(); @@ -714,6 +737,7 @@ bool Tween::remove_all() { bool Tween::seek(real_t p_time) { + pending_update ++; for(List::Element *E=interpolates.front();E;E=E->next()) { InterpolateData& data = E->get(); @@ -744,11 +768,13 @@ bool Tween::seek(real_t p_time) { _apply_tween_value(data, result); } + pending_update --; return true; } real_t Tween::tell() const { + pending_update ++; real_t pos = 0; for(const List::Element *E=interpolates.front();E;E=E->next()) { @@ -756,11 +782,13 @@ real_t Tween::tell() const { if(data.elapsed > pos) pos = data.elapsed; } + pending_update --; return pos; } real_t Tween::get_runtime() const { + pending_update ++; real_t runtime = 0; for(const List::Element *E=interpolates.front();E;E=E->next()) { @@ -769,6 +797,7 @@ real_t Tween::get_runtime() const { if(t > runtime) runtime = t; } + pending_update --; return runtime; } @@ -779,6 +808,12 @@ bool Tween::_calc_delta_val(const Variant& p_initial_val, const Variant& p_final Variant& delta_val = p_delta_val; switch(initial_val.get_type()) { + + case Variant::BOOL: + //delta_val = p_final_val; + delta_val = (int) p_final_val - (int) p_initial_val; + break; + case Variant::INT: delta_val = (int) final_val - (int) initial_val; break; @@ -873,7 +908,7 @@ bool Tween::_calc_delta_val(const Variant& p_initial_val, const Variant& p_final return true; } -bool Tween::interpolate_property(Node *p_node +bool Tween::interpolate_property(Object *p_object , String p_property , Variant p_initial_val , Variant p_final_val @@ -882,11 +917,12 @@ bool Tween::interpolate_property(Node *p_node , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters 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) p_final_val = p_final_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); @@ -894,7 +930,7 @@ bool Tween::interpolate_property(Node *p_node ERR_FAIL_COND_V(p_delay < 0, false); bool prop_valid = false; - p_node->get(p_property,&prop_valid); + p_object->get(p_property,&prop_valid); ERR_FAIL_COND_V(!prop_valid, false); InterpolateData data; @@ -903,7 +939,7 @@ bool Tween::interpolate_property(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_property; data.initial_val = p_initial_val; data.final_val = p_final_val; @@ -919,7 +955,7 @@ bool Tween::interpolate_property(Node *p_node return true; } -bool Tween::interpolate_method(Node *p_node +bool Tween::interpolate_method(Object *p_object , String p_method , Variant p_initial_val , Variant p_final_val @@ -928,18 +964,19 @@ bool Tween::interpolate_method(Node *p_node , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters 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) p_final_val = p_final_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); - ERR_FAIL_COND_V(!p_node->has_method(p_method), false); + ERR_FAIL_COND_V(!p_object->has_method(p_method), false); InterpolateData data; data.active = true; @@ -947,7 +984,7 @@ bool Tween::interpolate_method(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_method; data.initial_val = p_initial_val; data.final_val = p_final_val; @@ -963,16 +1000,17 @@ bool Tween::interpolate_method(Node *p_node return true; } -bool Tween::interpolate_callback(Node *p_node - , String p_callback +bool Tween::interpolate_callback(Object *p_object , real_t p_times_in_sec + , String p_callback , Variant p_arg ) { - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(pending_update != 0, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_times_in_sec < 0, false); - ERR_FAIL_COND_V(!p_node->has_method(p_callback), false); + ERR_FAIL_COND_V(!p_object->has_method(p_callback), false); InterpolateData data; data.active = true; @@ -980,30 +1018,33 @@ bool Tween::interpolate_callback(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_callback; data.times_in_sec = p_times_in_sec; data.delay = 0; data.arg = p_arg; + pending_update ++; interpolates.push_back(data); + pending_update --; return true; } -bool Tween::follow_property(Node *p_node +bool Tween::follow_property(Object *p_object , String p_property , Variant p_initial_val - , Node *p_target + , Object *p_target , String p_target_property , real_t p_times_in_sec , TransitionType p_trans_type , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_target == NULL, false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); @@ -1011,7 +1052,7 @@ bool Tween::follow_property(Node *p_node ERR_FAIL_COND_V(p_delay < 0, false); bool prop_valid = false; - p_node->get(p_property,&prop_valid); + p_object->get(p_property,&prop_valid); ERR_FAIL_COND_V(!prop_valid, false); bool target_prop_valid = false; @@ -1028,10 +1069,10 @@ bool Tween::follow_property(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_property; data.initial_val = p_initial_val; - data.target = p_target->get_path(); + data.target_id = p_target->get_instance_ID(); data.target_key = p_target_property; data.times_in_sec = p_times_in_sec; data.trans_type = p_trans_type; @@ -1042,27 +1083,28 @@ bool Tween::follow_property(Node *p_node return true; } -bool Tween::follow_method(Node *p_node +bool Tween::follow_method(Object *p_object , String p_method , Variant p_initial_val - , Node *p_target + , Object *p_target , String p_target_method , real_t p_times_in_sec , TransitionType p_trans_type , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters if(p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_target == NULL, false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); - ERR_FAIL_COND_V(!p_node->has_method(p_method), false); + ERR_FAIL_COND_V(!p_object->has_method(p_method), false); ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false); Variant::CallError error; @@ -1079,10 +1121,10 @@ bool Tween::follow_method(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_method; data.initial_val = p_initial_val; - data.target = p_target->get_path(); + data.target_id = p_target->get_instance_ID(); data.target_key = p_target_method; data.times_in_sec = p_times_in_sec; data.trans_type = p_trans_type; @@ -1093,9 +1135,9 @@ bool Tween::follow_method(Node *p_node return true; } -bool Tween::targeting_property(Node *p_node +bool Tween::targeting_property(Object *p_object , String p_property - , Node *p_initial + , Object *p_initial , String p_initial_property , Variant p_final_val , real_t p_times_in_sec @@ -1103,10 +1145,11 @@ bool Tween::targeting_property(Node *p_node , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_initial == NULL, false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); @@ -1114,7 +1157,7 @@ bool Tween::targeting_property(Node *p_node ERR_FAIL_COND_V(p_delay < 0, false); bool prop_valid = false; - p_node->get(p_property,&prop_valid); + p_object->get(p_property,&prop_valid); ERR_FAIL_COND_V(!prop_valid, false); bool initial_prop_valid = false; @@ -1131,9 +1174,9 @@ bool Tween::targeting_property(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_property; - data.target = p_initial->get_path(); + data.target_id = p_initial->get_instance_ID(); data.target_key = p_initial_property; data.initial_val = initial_val; data.final_val = p_final_val; @@ -1150,9 +1193,9 @@ bool Tween::targeting_property(Node *p_node } -bool Tween::targeting_method(Node *p_node +bool Tween::targeting_method(Object *p_object , String p_method - , Node *p_initial + , Object *p_initial , String p_initial_method , Variant p_final_val , real_t p_times_in_sec @@ -1160,17 +1203,18 @@ bool Tween::targeting_method(Node *p_node , EaseType p_ease_type , real_t p_delay ) { + ERR_FAIL_COND_V(pending_update != 0, false); // convert INT to REAL is better for interpolaters if(p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); - ERR_FAIL_COND_V(p_node == NULL, false); + ERR_FAIL_COND_V(p_object == NULL, false); ERR_FAIL_COND_V(p_initial == NULL, false); ERR_FAIL_COND_V(p_times_in_sec <= 0, false); ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); ERR_FAIL_COND_V(p_delay < 0, false); - ERR_FAIL_COND_V(!p_node->has_method(p_method), false); + ERR_FAIL_COND_V(!p_object->has_method(p_method), false); ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false); Variant::CallError error; @@ -1187,9 +1231,9 @@ bool Tween::targeting_method(Node *p_node data.finish = false; data.elapsed = 0; - data.path = p_node->get_path(); + data.id = p_object->get_instance_ID(); data.key = p_method; - data.target = p_initial->get_path(); + data.target_id = p_initial->get_instance_ID(); data.target_key = p_initial_method; data.initial_val = initial_val; data.final_val = p_final_val; @@ -1213,6 +1257,7 @@ Tween::Tween() { active=false; repeat=false; speed_scale=1; + pending_update=0; } Tween::~Tween() { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index c9d98633976..3e23cc362a5 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -54,15 +54,17 @@ public: TRANS_CIRC, TRANS_BOUNCE, TRANS_BACK, - TRANS_COUNT, + + TRANS_COUNT, }; enum EaseType { EASE_IN, EASE_OUT, EASE_IN_OUT, - EASE_OUT_IN, - EASE_COUNT, + EASE_OUT_IN, + + EASE_COUNT, }; private: @@ -82,12 +84,12 @@ private: InterpolateType type; bool finish; real_t elapsed; - NodePath path; + ObjectID id; StringName key; Variant initial_val; Variant delta_val; Variant final_val; - NodePath target; + ObjectID target_id; StringName target_key; real_t times_in_sec; TransitionType trans_type; @@ -102,6 +104,7 @@ private: bool active; bool repeat; float speed_scale; + mutable int pending_update; List interpolates; @@ -142,20 +145,20 @@ public: float get_speed() const; bool start(); - bool reset(Node *p_node, String p_key); + bool reset(Object *p_node, String p_key); bool reset_all(); - bool stop(Node *p_node, String p_key); + bool stop(Object *p_node, String p_key); bool stop_all(); - bool resume(Node *p_node, String p_key); + bool resume(Object *p_node, String p_key); bool resume_all(); - bool remove(Node *p_node, String p_key); + bool remove(Object *p_node, String p_key); bool remove_all(); bool seek(real_t p_time); real_t tell() const; real_t get_runtime() const; - bool interpolate_property(Node *p_node + bool interpolate_property(Object *p_node , String p_property , Variant p_initial_val , Variant p_final_val @@ -165,7 +168,7 @@ public: , real_t p_delay = 0 ); - bool interpolate_method(Node *p_node + bool interpolate_method(Object *p_node , String p_method , Variant p_initial_val , Variant p_final_val @@ -175,16 +178,16 @@ public: , real_t p_delay = 0 ); - bool interpolate_callback(Node *p_node - , String p_callback + bool interpolate_callback(Object *p_node , real_t p_times_in_sec + , String p_callback , Variant p_arg = Variant() ); - bool follow_property(Node *p_node + bool follow_property(Object *p_node , String p_property , Variant p_initial_val - , Node *p_target + , Object *p_target , String p_target_property , real_t p_times_in_sec , TransitionType p_trans_type @@ -192,10 +195,10 @@ public: , real_t p_delay = 0 ); - bool follow_method(Node *p_node + bool follow_method(Object *p_node , String p_method , Variant p_initial_val - , Node *p_target + , Object *p_target , String p_target_method , real_t p_times_in_sec , TransitionType p_trans_type @@ -203,9 +206,9 @@ public: , real_t p_delay = 0 ); - bool targeting_property(Node *p_node + bool targeting_property(Object *p_node , String p_property - , Node *p_initial + , Object *p_initial , String p_initial_property , Variant p_final_val , real_t p_times_in_sec @@ -214,9 +217,9 @@ public: , real_t p_delay = 0 ); - bool targeting_method(Node *p_node + bool targeting_method(Object *p_node , String p_method - , Node *p_initial + , Object *p_initial , String p_initial_method , Variant p_final_val , real_t p_times_in_sec