-More strict argument type-checking, will make many bugs visible, fixes #1809

-added NOTIFICATION_INSTANCED
This commit is contained in:
Juan Linietsky 2015-05-04 18:30:57 -03:00
parent 6f8bd89931
commit 2d396fb710
7 changed files with 263 additions and 9 deletions

View file

@ -98,7 +98,7 @@ struct VariantCaster<m_enum> {\
#define CHECK_ARG(m_arg)\ #define CHECK_ARG(m_arg)\
if ((m_arg-1)<p_arg_count) {\ if ((m_arg-1)<p_arg_count) {\
Variant::Type argtype=get_argument_type(m_arg-1);\ Variant::Type argtype=get_argument_type(m_arg-1);\
if (!Variant::can_convert(p_args[m_arg-1]->get_type(),argtype)) {\ if (!Variant::can_convert_strict(p_args[m_arg-1]->get_type(),argtype)) {\
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
r_error.argument=m_arg-1;\ r_error.argument=m_arg-1;\
r_error.expected=argtype;\ r_error.expected=argtype;\

View file

@ -214,7 +214,7 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
static const Type valid[]={ static const Type valid[]={
INT, INT,
REAL, REAL,
//STRING, STRING,
NIL, NIL,
}; };
@ -225,7 +225,7 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
static const Type valid[]={ static const Type valid[]={
BOOL, BOOL,
REAL, REAL,
//STRING, STRING,
NIL, NIL,
}; };
@ -237,7 +237,7 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
static const Type valid[]={ static const Type valid[]={
BOOL, BOOL,
INT, INT,
//STRING, STRING,
NIL, NIL,
}; };
@ -258,12 +258,262 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
case MATRIX32: { case MATRIX32: {
static const Type invalid[]={ static const Type valid[]={
TRANSFORM, TRANSFORM,
NIL NIL
}; };
invalid_types=invalid; valid_types=valid;
} break;
case QUAT: {
static const Type valid[]={
MATRIX3,
NIL
};
valid_types=valid;
} break;
case MATRIX3: {
static const Type valid[]={
QUAT,
NIL
};
valid_types=valid;
} break;
case TRANSFORM: {
static const Type valid[]={
MATRIX32,
QUAT,
MATRIX3,
NIL
};
valid_types=valid;
} break;
case COLOR: {
static const Type valid[] = {
//STRING,
//INT,
NIL,
};
valid_types = valid;
} break;
case _RID: {
static const Type valid[]={
OBJECT,
NIL
};
valid_types=valid;
} break;
case OBJECT: {
static const Type valid[]={
NIL
};
valid_types=valid;
} break;
case NODE_PATH: {
static const Type valid[]={
STRING,
NIL
};
valid_types=valid;
} break;
case ARRAY: {
static const Type valid[]={
RAW_ARRAY,
INT_ARRAY,
STRING_ARRAY,
REAL_ARRAY,
COLOR_ARRAY,
VECTOR2_ARRAY,
VECTOR3_ARRAY,
NIL
};
valid_types=valid;
} break;
// arrays
case RAW_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case INT_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case REAL_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case STRING_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case VECTOR2_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case VECTOR3_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
case COLOR_ARRAY: {
static const Type valid[]={
ARRAY,
NIL
};
valid_types=valid;
} break;
default: {}
}
if (valid_types) {
int i=0;
while(valid_types[i]!=NIL) {
if (p_type_from==valid_types[i])
return true;
i++;
}
} else if (invalid_types) {
int i=0;
while(invalid_types[i]!=NIL) {
if (p_type_from==invalid_types[i])
return false;
i++;
}
}
return false;
}
bool Variant::can_convert_strict(Variant::Type p_type_from,Variant::Type p_type_to) {
if (p_type_from==p_type_to)
return true;
if (p_type_to==NIL && p_type_from!=NIL) //nil can convert to anything
return true;
if (p_type_from == NIL) {
return (p_type_to == OBJECT);
};
const Type *valid_types=NULL;
const Type *invalid_types=NULL;
switch(p_type_to) {
case BOOL: {
static const Type valid[]={
//INT,
//REAL,
//STRING,
NIL,
};
valid_types=valid;
} break;
case INT: {
static const Type valid[]={
//BOOL,
REAL,
//STRING,
NIL,
};
valid_types=valid;
} break;
case REAL: {
static const Type valid[]={
//BOOL,
INT,
//STRING,
NIL,
};
valid_types=valid;
} break;
case STRING: {
static const Type valid[]={
NODE_PATH,
NIL
};
valid_types=valid;
} break;
case MATRIX32: {
static const Type valid[]={
TRANSFORM,
NIL
};
valid_types=valid;
} break; } break;
case QUAT: { case QUAT: {

View file

@ -166,6 +166,7 @@ public:
_FORCE_INLINE_ Type get_type() const { return type; } _FORCE_INLINE_ Type get_type() const { return type; }
static String get_type_name(Variant::Type p_type); static String get_type_name(Variant::Type p_type);
static bool can_convert(Type p_type_from, Type p_type_to); static bool can_convert(Type p_type_from, Type p_type_to);
static bool can_convert_strict(Type p_type_from, Type p_type_to);

View file

@ -56,7 +56,7 @@ func _integrate_forces(s):
state=STATE_DYING state=STATE_DYING
#lv=s.get_contact_local_normal(i)*400 #lv=s.get_contact_local_normal(i)*400
s.set_angular_velocity(sign(dp.x)*33.0) s.set_angular_velocity(sign(dp.x)*33.0)
set_friction(true) set_friction(1)
cc.disable() cc.disable()
get_node("sound").play("hit") get_node("sound").play("hit")

View file

@ -45,7 +45,7 @@ func _integrate_forces(state):
state.set_angular_velocity( -dp.cross(up).normalized() *33.0) state.set_angular_velocity( -dp.cross(up).normalized() *33.0)
get_node("AnimationPlayer").play("impact") get_node("AnimationPlayer").play("impact")
get_node("AnimationPlayer").queue("explode") get_node("AnimationPlayer").queue("explode")
set_friction(true) set_friction(1)
cc.disabled=true cc.disabled=true
get_node("sound").play("hit") get_node("sound").play("hit")
return return

View file

@ -170,6 +170,7 @@ public:
NOTIFICATION_PROCESS = 17, NOTIFICATION_PROCESS = 17,
NOTIFICATION_PARENTED=18, NOTIFICATION_PARENTED=18,
NOTIFICATION_UNPARENTED=19, NOTIFICATION_UNPARENTED=19,
NOTIFICATION_INSTANCED=20,
}; };
/* NODE/TREE */ /* NODE/TREE */

View file

@ -182,6 +182,8 @@ Node *PackedScene::instance(bool p_gen_edit_state) const {
if (get_path()!="" && get_path().find("::")==-1) if (get_path()!="" && get_path().find("::")==-1)
s->set_filename(get_path()); s->set_filename(get_path());
s->notification(Node::NOTIFICATION_INSTANCED);
return ret_nodes[0]; return ret_nodes[0];
} }