diff options
author | George Marques <george@gmarqu.es> | 2018-05-29 23:16:56 -0300 |
---|---|---|
committer | George Marques <george@gmarqu.es> | 2018-07-20 21:55:17 -0300 |
commit | 4b18c4e448c93fbb44c80b89e744cfacea8d8bc4 (patch) | |
tree | 82ee55b5fd0cc3fbe112344b029a5d5563094592 /modules/gdscript/gdscript_function.h | |
parent | 743053734f187c220250d88e4e475b7a87767cbc (diff) | |
download | redot-engine-4b18c4e448c93fbb44c80b89e744cfacea8d8bc4.tar.gz |
Add typed instructions to GDScript
- Typed assignment (built-in, native, and script).
- Cast (built-in conversion; native and script checks).
- Check type of functions arguments on call.
- Check type of members on set.
Diffstat (limited to 'modules/gdscript/gdscript_function.h')
-rw-r--r-- | modules/gdscript/gdscript_function.h | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 62b6871b76..3ce84290fd 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -54,6 +54,79 @@ struct GDScriptDataType { StringName native_type; Ref<Script> script_type; + bool is_type(const Variant &p_variant, bool p_allow_implicit_conversion = false) const { + if (!has_type) return true; // Can't type check + + switch (kind) { + case BUILTIN: { + Variant::Type var_type = p_variant.get_type(); + bool valid = builtin_type == var_type; + if (!valid && p_allow_implicit_conversion) { + valid = Variant::can_convert_strict(var_type, builtin_type); + } + return valid; + } break; + case NATIVE: { + if (p_variant.get_type() == Variant::NIL) { + return true; + } + if (p_variant.get_type() != Variant::OBJECT) { + return false; + } + Object *obj = p_variant.operator Object *(); + if (obj && !ClassDB::is_parent_class(obj->get_class_name(), native_type)) { + return false; + } + return true; + } break; + case SCRIPT: + case GDSCRIPT: { + if (p_variant.get_type() == Variant::NIL) { + return true; + } + if (p_variant.get_type() != Variant::OBJECT) { + return false; + } + Object *obj = p_variant.operator Object *(); + Ref<Script> base = obj && obj->get_script_instance() ? obj->get_script_instance()->get_script() : NULL; + bool valid = false; + while (base.is_valid()) { + if (base == script_type) { + valid = true; + break; + } + base = base->get_base_script(); + } + return valid; + } break; + } + return false; + } + + operator PropertyInfo() const { + PropertyInfo info; + if (has_type) { + switch (kind) { + case BUILTIN: { + info.type = builtin_type; + } break; + case NATIVE: { + info.type = Variant::OBJECT; + info.class_name = native_type; + } break; + case SCRIPT: + case GDSCRIPT: { + info.type = Variant::OBJECT; + info.class_name = script_type->get_instance_base_type(); + } break; + } + } else { + info.type = Variant::NIL; + info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } + return info; + } + GDScriptDataType() : has_type(false) {} }; @@ -72,6 +145,12 @@ public: OPCODE_ASSIGN, OPCODE_ASSIGN_TRUE, OPCODE_ASSIGN_FALSE, + OPCODE_ASSIGN_TYPED_BUILTIN, + OPCODE_ASSIGN_TYPED_NATIVE, + OPCODE_ASSIGN_TYPED_SCRIPT, + OPCODE_CAST_TO_BUILTIN, + OPCODE_CAST_TO_NATIVE, + OPCODE_CAST_TO_SCRIPT, OPCODE_CONSTRUCT, //only for basic types!! OPCODE_CONSTRUCT_ARRAY, OPCODE_CONSTRUCT_DICTIONARY, |