diff options
Diffstat (limited to 'modules/gdscript')
31 files changed, 274 insertions, 166 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index e170667a30..95818e5fcf 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -921,7 +921,7 @@ [/codeblock] </description> </method> - <method name="rand_range"> + <method name="randf_range"> <return type="float"> </return> <argument index="0" name="from" type="float"> @@ -931,7 +931,22 @@ <description> Random range, any floating point value between [code]from[/code] and [code]to[/code]. [codeblock] - prints(rand_range(0, 1), rand_range(0, 1)) # Prints e.g. 0.135591 0.405263 + prints(randf_range(-10, 10), randf_range(-10, 10)) # Prints e.g. -3.844535 7.45315 + [/codeblock] + </description> + </method> + <method name="randi_range"> + <return type="int"> + </return> + <argument index="0" name="from" type="int"> + </argument> + <argument index="1" name="to" type="int"> + </argument> + <description> + Random range, any 32-bit integer value between [code]from[/code] and [code]to[/code] (inclusive). If [code]to[/code] is lesser than [code]from[/code] they are swapped. + [codeblock] + print(randi_range(0, 1)) # Prints 0 or 1 + print(randi_range(-10, 1000)) # Prints any number from -10 to 1000 [/codeblock] </description> </method> diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index 5ea416d4cc..d763df01f5 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_TRANSLATION_PARSER_PLUGIN_H #define GDSCRIPT_TRANSLATION_PARSER_PLUGIN_H -#include "core/set.h" +#include "core/templates/set.h" #include "editor/editor_translation_parser.h" #include "modules/gdscript/gdscript_parser.h" #include "modules/regex/regex.h" diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index e70e3f7272..a73268a79d 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -32,13 +32,13 @@ #include <stdint.h> +#include "core/config/engine.h" +#include "core/config/project_settings.h" +#include "core/core_constants.h" #include "core/core_string_names.h" -#include "core/engine.h" -#include "core/global_constants.h" #include "core/io/file_access_encrypted.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "gdscript_analyzer.h" #include "gdscript_cache.h" #include "gdscript_compiler.h" @@ -1500,9 +1500,9 @@ void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) { void GDScriptLanguage::init() { //populate global constants - int gcc = GlobalConstants::get_global_constant_count(); + int gcc = CoreConstants::get_global_constant_count(); for (int i = 0; i < gcc; i++) { - _add_global(StaticCString::create(GlobalConstants::get_global_constant_name(i)), GlobalConstants::get_global_constant_value(i)); + _add_global(StaticCString::create(CoreConstants::get_global_constant_name(i)), CoreConstants::get_global_constant_value(i)); } _add_global(StaticCString::create("PI"), Math_PI); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 79317ff846..b69a6e39c0 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -35,7 +35,7 @@ #include "core/debugger/script_debugger.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/script_language.h" +#include "core/object/script_language.h" #include "gdscript_function.h" class GDScriptNativeClass : public Reference { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 943a49060f..a1de17b5a1 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -30,12 +30,12 @@ #include "gdscript_analyzer.h" -#include "core/class_db.h" -#include "core/hash_map.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/object/class_db.h" +#include "core/object/script_language.h" #include "core/os/file_access.h" -#include "core/project_settings.h" -#include "core/script_language.h" +#include "core/templates/hash_map.h" #include "gdscript.h" // TODO: Move this to a central location (maybe core?). @@ -577,6 +577,12 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas GDScriptParser::DataType datatype = member.constant->get_datatype(); if (member.constant->initializer) { + if (member.constant->initializer->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast<GDScriptParser::ArrayNode *>(member.constant->initializer)); + } else if (member.constant->initializer->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(member.constant->initializer)); + } + if (!member.constant->initializer->is_constant) { push_error(R"(Initializer for a constant must be a constant expression.)", member.constant->initializer); } @@ -1113,6 +1119,11 @@ void GDScriptAnalyzer::resolve_constant(GDScriptParser::ConstantNode *p_constant GDScriptParser::DataType type; reduce_expression(p_constant->initializer); + if (p_constant->initializer->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast<GDScriptParser::ArrayNode *>(p_constant->initializer)); + } else if (p_constant->initializer->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(p_constant->initializer)); + } if (!p_constant->initializer->is_constant) { push_error(vformat(R"(Assigned value for constant "%s" isn't a constant expression.)", p_constant->identifier->name), p_constant->initializer); @@ -1422,22 +1433,9 @@ void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expre } void GDScriptAnalyzer::reduce_array(GDScriptParser::ArrayNode *p_array) { - bool all_is_constant = true; - for (int i = 0; i < p_array->elements.size(); i++) { GDScriptParser::ExpressionNode *element = p_array->elements[i]; reduce_expression(element); - all_is_constant = all_is_constant && element->is_constant; - } - - if (all_is_constant) { - Array array; - array.resize(p_array->elements.size()); - for (int i = 0; i < p_array->elements.size(); i++) { - array[i] = p_array->elements[i]->reduced_value; - } - p_array->is_constant = true; - p_array->reduced_value = array; } // It's array in any case. @@ -1984,8 +1982,6 @@ void GDScriptAnalyzer::reduce_cast(GDScriptParser::CastNode *p_cast) { } void GDScriptAnalyzer::reduce_dictionary(GDScriptParser::DictionaryNode *p_dictionary) { - bool all_is_constant = true; - HashMap<Variant, GDScriptParser::ExpressionNode *, VariantHasher, VariantComparator> elements; for (int i = 0; i < p_dictionary->elements.size(); i++) { @@ -1994,7 +1990,6 @@ void GDScriptAnalyzer::reduce_dictionary(GDScriptParser::DictionaryNode *p_dicti reduce_expression(element.key); } reduce_expression(element.value); - all_is_constant = all_is_constant && element.key->is_constant && element.value->is_constant; if (element.key->is_constant) { if (elements.has(element.key->reduced_value)) { @@ -2005,16 +2000,6 @@ void GDScriptAnalyzer::reduce_dictionary(GDScriptParser::DictionaryNode *p_dicti } } - if (all_is_constant) { - Dictionary dict; - for (int i = 0; i < p_dictionary->elements.size(); i++) { - const GDScriptParser::DictionaryNode::Pair &element = p_dictionary->elements[i]; - dict[element.key->reduced_value] = element.value->reduced_value; - } - p_dictionary->is_constant = true; - p_dictionary->reduced_value = dict; - } - // It's dictionary in any case. GDScriptParser::DataType dict_type; dict_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; @@ -2294,10 +2279,12 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident StringName name = p_identifier->name; p_identifier->source = GDScriptParser::IdentifierNode::UNDEFINED_SOURCE; - // Check globals. - if (GDScriptParser::get_builtin_type(name) < Variant::VARIANT_MAX) { + // Check globals. We make an exception for Variant::OBJECT because it's the base class for + // non-builtin types so we allow doing e.g. Object.new() + Variant::Type builtin_type = GDScriptParser::get_builtin_type(name); + if (builtin_type != Variant::OBJECT && builtin_type < Variant::VARIANT_MAX) { if (can_be_builtin) { - p_identifier->set_datatype(make_builtin_meta_type(GDScriptParser::get_builtin_type(name))); + p_identifier->set_datatype(make_builtin_meta_type(builtin_type)); return; } else { push_error(R"(Builtin type cannot be used as a name on its own.)", p_identifier); @@ -2451,7 +2438,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri if (p_subscript->base->is_constant) { // Just try to get it. bool valid = false; - Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, &valid); + Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); if (!valid) { push_error(vformat(R"(Cannot get member "%s" from "%s".)", p_subscript->attribute->name, p_subscript->base->reduced_value), p_subscript->index); } else { @@ -2737,6 +2724,46 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op) p_unary_op->set_datatype(result); } +void GDScriptAnalyzer::const_fold_array(GDScriptParser::ArrayNode *p_array) { + bool all_is_constant = true; + + for (int i = 0; i < p_array->elements.size(); i++) { + GDScriptParser::ExpressionNode *element = p_array->elements[i]; + all_is_constant = all_is_constant && element->is_constant; + if (!all_is_constant) { + return; + } + } + + Array array; + array.resize(p_array->elements.size()); + for (int i = 0; i < p_array->elements.size(); i++) { + array[i] = p_array->elements[i]->reduced_value; + } + p_array->is_constant = true; + p_array->reduced_value = array; +} + +void GDScriptAnalyzer::const_fold_dictionary(GDScriptParser::DictionaryNode *p_dictionary) { + bool all_is_constant = true; + + for (int i = 0; i < p_dictionary->elements.size(); i++) { + const GDScriptParser::DictionaryNode::Pair &element = p_dictionary->elements[i]; + all_is_constant = all_is_constant && element.key->is_constant && element.value->is_constant; + if (!all_is_constant) { + return; + } + } + + Dictionary dict; + for (int i = 0; i < p_dictionary->elements.size(); i++) { + const GDScriptParser::DictionaryNode::Pair &element = p_dictionary->elements[i]; + dict[element.key->reduced_value] = element.value->reduced_value; + } + p_dictionary->is_constant = true; + p_dictionary->reduced_value = dict; +} + GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_value, const GDScriptParser::Node *p_source) { GDScriptParser::DataType result; result.is_constant = true; diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h index c3911cce76..0a952cc621 100644 --- a/modules/gdscript/gdscript_analyzer.h +++ b/modules/gdscript/gdscript_analyzer.h @@ -31,9 +31,9 @@ #ifndef GDSCRIPT_ANALYZER_H #define GDSCRIPT_ANALYZER_H -#include "core/object.h" -#include "core/reference.h" -#include "core/set.h" +#include "core/object/object.h" +#include "core/object/reference.h" +#include "core/templates/set.h" #include "gdscript_cache.h" #include "gdscript_parser.h" @@ -89,6 +89,9 @@ class GDScriptAnalyzer { void reduce_ternary_op(GDScriptParser::TernaryOpNode *p_ternary_op); void reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op); + void const_fold_array(GDScriptParser::ArrayNode *p_array); + void const_fold_dictionary(GDScriptParser::DictionaryNode *p_dictionary); + // Helpers. GDScriptParser::DataType type_from_variant(const Variant &p_value, const GDScriptParser::Node *p_source); GDScriptParser::DataType type_from_metatype(const GDScriptParser::DataType &p_meta_type) const; diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index eabf53581d..cc9e87b882 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -580,8 +580,8 @@ void GDScriptByteCodeGenerator::write_endif() { } void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Address &p_list) { - int counter_pos = increase_stack() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); - int container_pos = increase_stack() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + int counter_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); + int container_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); current_breaks_to_patch.push_back(List<int>()); @@ -629,7 +629,9 @@ void GDScriptByteCodeGenerator::write_endfor() { } current_breaks_to_patch.pop_back(); - current_stack_size -= 2; // Remove loop temporaries. + // Remove loop temporaries. + pop_temporary(); + pop_temporary(); } void GDScriptByteCodeGenerator::start_while_condition() { diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 57b95f5b21..95d24a8b08 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -31,7 +31,7 @@ #include "gdscript_cache.h" #include "core/os/file_access.h" -#include "core/vector.h" +#include "core/templates/vector.h" #include "gdscript.h" #include "gdscript_analyzer.h" #include "gdscript_parser.h" diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index 865df34051..90c5884985 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -31,10 +31,10 @@ #ifndef GDSCRIPT_CACHE_H #define GDSCRIPT_CACHE_H -#include "core/hash_map.h" +#include "core/object/reference.h" #include "core/os/mutex.h" -#include "core/reference.h" -#include "core/set.h" +#include "core/templates/hash_map.h" +#include "core/templates/set.h" #include "gdscript.h" class GDScriptAnalyzer; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 31e1e6ba23..9872a61423 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -32,8 +32,8 @@ #define GDSCRIPT_CODEGEN #include "core/io/multiplayer_api.h" -#include "core/string_name.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/variant/variant.h" #include "gdscript_function.h" #include "gdscript_functions.h" diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index db02079d26..157c801f56 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_COMPILER_H #define GDSCRIPT_COMPILER_H -#include "core/set.h" +#include "core/templates/set.h" #include "gdscript.h" #include "gdscript_codegen.h" #include "gdscript_function.h" @@ -51,12 +51,11 @@ class GDScriptCompiler { GDScriptCodeGenerator *generator = nullptr; Map<StringName, GDScriptCodeGenerator::Address> parameters; Map<StringName, GDScriptCodeGenerator::Address> locals; - List<Set<StringName>> locals_in_scope; + List<Map<StringName, GDScriptCodeGenerator::Address>> locals_stack; GDScriptCodeGenerator::Address add_local(const StringName &p_name, const GDScriptDataType &p_type) { uint32_t addr = generator->add_local(p_name, p_type); locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::LOCAL_VARIABLE, addr, p_type); - locals_in_scope.back()->get().insert(p_name); return locals[p_name]; } @@ -102,17 +101,14 @@ class GDScriptCompiler { } void start_block() { - Set<StringName> scope; - locals_in_scope.push_back(scope); + Map<StringName, GDScriptCodeGenerator::Address> old_locals = locals; + locals_stack.push_back(old_locals); generator->start_block(); } void end_block() { - Set<StringName> &scope = locals_in_scope.back()->get(); - for (Set<StringName>::Element *E = scope.front(); E; E = E->next()) { - locals.erase(E->get()); - } - locals_in_scope.pop_back(); + locals = locals_stack.back()->get(); + locals_stack.pop_back(); generator->end_block(); } }; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 2e372575da..605883f6df 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -30,8 +30,8 @@ #include "gdscript.h" -#include "core/engine.h" -#include "core/global_constants.h" +#include "core/config/engine.h" +#include "core/core_constants.h" #include "core/os/file_access.h" #include "gdscript_analyzer.h" #include "gdscript_compiler.h" @@ -39,7 +39,7 @@ #include "gdscript_tokenizer.h" #ifdef TOOLS_ENABLED -#include "core/project_settings.h" +#include "core/config/project_settings.h" #include "editor/editor_file_system.h" #include "editor/editor_settings.h" #endif @@ -383,8 +383,8 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> } bool skip = false; - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { - if (E->key() == GlobalConstants::get_global_constant_name(i)) { + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { + if (E->key() == CoreConstants::get_global_constant_name(i)) { skip = true; break; } @@ -792,6 +792,9 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class, continue; } option = ScriptCodeCompletionOption(member.constant->identifier->name, ScriptCodeCompletionOption::KIND_CONSTANT); + if (member.constant->initializer) { + option.default_value = member.constant->initializer->reduced_value; + } break; case GDScriptParser::ClassNode::Member::CLASS: if (p_only_functions) { @@ -2136,9 +2139,9 @@ static void _find_enumeration_candidates(GDScriptParser::CompletionContext &p_co r_result.insert(option.display, option); } } else { - for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { - if (GlobalConstants::get_global_constant_enum(i) == current_enum) { - ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); + for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { + if (CoreConstants::get_global_constant_enum(i) == current_enum) { + ScriptCodeCompletionOption option(CoreConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); r_result.insert(option.display, option); } } @@ -2404,6 +2407,11 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path Variant::get_constants_for_type(completion_context.builtin_type, &constants); for (const List<StringName>::Element *E = constants.front(); E != nullptr; E = E->next()) { ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); + bool valid = false; + Variant default_value = Variant::get_constant_value(completion_context.builtin_type, E->get(), &valid); + if (valid) { + option.default_value = default_value; + } options.insert(option.display, option); } } break; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index e59f99fc56..3a7b38dac5 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -35,7 +35,7 @@ #include "gdscript_functions.h" #ifdef DEBUG_ENABLED -#include "core/string_builder.h" +#include "core/string/string_builder.h" #endif Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { @@ -620,7 +620,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const StringName *index = &_global_names_ptr[indexname]; bool valid; - dst->set_named(*index, *value, &valid); + dst->set_named(*index, *value, valid); #ifdef DEBUG_ENABLED if (!valid) { @@ -647,10 +647,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool valid; #ifdef DEBUG_ENABLED //allow better error message in cases where src and dst are the same stack position - Variant ret = src->get_named(*index, &valid); + Variant ret = src->get_named(*index, valid); #else - *dst = src->get_named(*index, &valid); + *dst = src->get_named(*index, valid); #endif #ifdef DEBUG_ENABLED if (!valid) { @@ -1093,6 +1093,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } } + } else if (methodstr == "call_recursive" && basestr == "TreeItem") { + if (argc >= 1) { + methodstr = String(*argptrs[0]) + " (via TreeItem.call_recursive)"; + if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { + err.argument += 1; + } + } } err_text = _get_call_error(err, "function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs); OPCODE_BREAK; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index c98ac09310..50eadcaf86 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -31,13 +31,13 @@ #ifndef GDSCRIPT_FUNCTION_H #define GDSCRIPT_FUNCTION_H +#include "core/object/reference.h" +#include "core/object/script_language.h" #include "core/os/thread.h" -#include "core/pair.h" -#include "core/reference.h" -#include "core/script_language.h" -#include "core/self_list.h" -#include "core/string_name.h" -#include "core/variant.h" +#include "core/string/string_name.h" +#include "core/templates/pair.h" +#include "core/templates/self_list.h" +#include "core/variant/variant.h" class GDScriptInstance; class GDScript; diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 31ce63bc6e..3c82545190 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -30,14 +30,13 @@ #include "gdscript_functions.h" -#include "core/class_db.h" -#include "core/func_ref.h" #include "core/io/json.h" #include "core/io/marshalls.h" #include "core/math/math_funcs.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #include "core/os/os.h" -#include "core/reference.h" -#include "core/variant_parser.h" +#include "core/variant/variant_parser.h" #include "gdscript.h" const char *GDScriptFunctions::get_func_name(Function p_func) { @@ -83,7 +82,8 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "randomize", "randi", "randf", - "rand_range", + "randf_range", + "randi_range", "seed", "rand_seed", "deg2rad", @@ -99,7 +99,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "clamp", "nearest_po2", "weakref", - "funcref", "convert", "typeof", "type_exists", @@ -419,7 +418,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Math::randomize(); r_ret = Variant(); } break; - case MATH_RAND: { + case MATH_RANDI: { VALIDATE_ARG_COUNT(0); r_ret = Math::rand(); } break; @@ -427,12 +426,18 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(0); r_ret = Math::randf(); } break; - case MATH_RANDOM: { + case MATH_RANDF_RANGE: { VALIDATE_ARG_COUNT(2); VALIDATE_ARG_NUM(0); VALIDATE_ARG_NUM(1); r_ret = Math::random((double)*p_args[0], (double)*p_args[1]); } break; + case MATH_RANDI_RANGE: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret = Math::random((int)*p_args[0], (int)*p_args[1]); + } break; case MATH_SEED: { VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); @@ -582,31 +587,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } } break; - case FUNC_FUNCREF: { - VALIDATE_ARG_COUNT(2); - if (p_args[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - r_ret = Variant(); - return; - } - if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING; - r_ret = Variant(); - return; - } - - Ref<FuncRef> fr = memnew(FuncRef); - - fr->set_instance(*p_args[0]); - fr->set_function(*p_args[1]); - - r_ret = fr; - - } break; case TYPE_CONVERT: { VALIDATE_ARG_COUNT(2); VALIDATE_ARG_NUM(1); @@ -1655,7 +1635,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { mi.return_val.type = Variant::NIL; return mi; } break; - case MATH_RAND: { + case MATH_RANDI: { MethodInfo mi("randi"); mi.return_val.type = Variant::INT; return mi; @@ -1665,11 +1645,16 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { mi.return_val.type = Variant::FLOAT; return mi; } break; - case MATH_RANDOM: { - MethodInfo mi("rand_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to")); + case MATH_RANDF_RANGE: { + MethodInfo mi("randf_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to")); mi.return_val.type = Variant::FLOAT; return mi; } break; + case MATH_RANDI_RANGE: { + MethodInfo mi("randi_range", PropertyInfo(Variant::INT, "from"), PropertyInfo(Variant::INT, "to")); + mi.return_val.type = Variant::INT; + return mi; + } break; case MATH_SEED: { MethodInfo mi("seed", PropertyInfo(Variant::INT, "seed")); mi.return_val.type = Variant::NIL; @@ -1749,13 +1734,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; - case FUNC_FUNCREF: { - MethodInfo mi("funcref", PropertyInfo(Variant::OBJECT, "instance"), PropertyInfo(Variant::STRING, "funcname")); - mi.return_val.type = Variant::OBJECT; - mi.return_val.class_name = "FuncRef"; - return mi; - - } break; case TYPE_CONVERT: { MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::INT, "type")); mi.return_val.type = Variant::NIL; diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h index 2c6dc02913..005b49c5da 100644 --- a/modules/gdscript/gdscript_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -31,7 +31,7 @@ #ifndef GDSCRIPT_FUNCTIONS_H #define GDSCRIPT_FUNCTIONS_H -#include "core/variant.h" +#include "core/variant/variant.h" class GDScriptFunctions { public: @@ -73,9 +73,10 @@ public: MATH_MOVE_TOWARD, MATH_DECTIME, MATH_RANDOMIZE, - MATH_RAND, + MATH_RANDI, MATH_RANDF, - MATH_RANDOM, + MATH_RANDF_RANGE, + MATH_RANDI_RANGE, MATH_SEED, MATH_RANDSEED, MATH_DEG2RAD, @@ -91,7 +92,6 @@ public: LOGIC_CLAMP, LOGIC_NEAREST_PO2, OBJ_WEAKREF, - FUNC_FUNCREF, TYPE_CONVERT, TYPE_OF, TYPE_EXISTS, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 2a69db130b..6bf8a3a908 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -30,15 +30,15 @@ #include "gdscript_parser.h" +#include "core/config/project_settings.h" #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "core/os/file_access.h" -#include "core/project_settings.h" #include "gdscript.h" #ifdef DEBUG_ENABLED #include "core/os/os.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" #endif // DEBUG_ENABLED #ifdef TOOLS_ENABLED diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 4c9473c7bd..b24acc4778 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -31,23 +31,23 @@ #ifndef GDSCRIPT_PARSER_H #define GDSCRIPT_PARSER_H -#include "core/hash_map.h" #include "core/io/multiplayer_api.h" -#include "core/list.h" -#include "core/map.h" -#include "core/reference.h" -#include "core/resource.h" -#include "core/script_language.h" -#include "core/string_name.h" -#include "core/ustring.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/io/resource.h" +#include "core/object/reference.h" +#include "core/object/script_language.h" +#include "core/string/string_name.h" +#include "core/string/ustring.h" +#include "core/templates/hash_map.h" +#include "core/templates/list.h" +#include "core/templates/map.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" #include "gdscript_cache.h" #include "gdscript_functions.h" #include "gdscript_tokenizer.h" #ifdef DEBUG_ENABLED -#include "core/string_builder.h" +#include "core/string/string_builder.h" #include "gdscript_warning.h" #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 9a40aa50ac..b91777ede1 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -30,7 +30,7 @@ #include "gdscript_tokenizer.h" -#include "core/error_macros.h" +#include "core/error/error_macros.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 4453982d08..d51f1f250f 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -31,10 +31,10 @@ #ifndef GDSCRIPT_TOKENIZER_H #define GDSCRIPT_TOKENIZER_H -#include "core/list.h" -#include "core/set.h" -#include "core/variant.h" -#include "core/vector.h" +#include "core/templates/list.h" +#include "core/templates/set.h" +#include "core/templates/vector.h" +#include "core/variant/variant.h" class GDScriptTokenizer { public: diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp index 105facd9d0..56704d3e0a 100644 --- a/modules/gdscript/gdscript_warning.cpp +++ b/modules/gdscript/gdscript_warning.cpp @@ -30,7 +30,7 @@ #include "gdscript_warning.h" -#include "core/variant.h" +#include "core/variant/variant.h" #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index e183d6f302..e0857703d8 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -33,8 +33,8 @@ #ifdef DEBUG_ENABLED -#include "core/ustring.h" -#include "core/vector.h" +#include "core/string/ustring.h" +#include "core/templates/vector.h" class GDScriptWarning { public: diff --git a/modules/gdscript/icons/GDScript.svg b/modules/gdscript/icons/GDScript.svg index 953bb9ae9e..aa59125ea9 100644 --- a/modules/gdscript/icons/GDScript.svg +++ b/modules/gdscript/icons/GDScript.svg @@ -1,5 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m7 1l-0.56445 2.2578a5 5 0 0 0 -0.68945 0.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -0.28516 0.68555l-2.2539 0.5625v2l2.2578 0.56445a5 5 0 0 0 0.2793 0.6875l-1.1934 1.9902 1.4141 1.4141 1.9941-1.1953a5 5 0 0 0 0.68555 0.28516l0.5625 2.2539h2l0.56445-2.2578a5 5 0 0 0 0.6875 -0.2793l1.9902 1.1934 1.4141-1.4141-1.1953-1.9941a5 5 0 0 0 0.28516 -0.68555l2.2539-0.5625v-2l-2.2578-0.56445a5 5 0 0 0 -0.2793 -0.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -0.68555 -0.28516l-0.5625-2.2539h-2zm1 5a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#e0e0e0"/> -</g> -</svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2l2.2578.56445a5 5 0 0 0 .2793.6875l-1.1934 1.9902 1.4141 1.4141 1.9941-1.1953a5 5 0 0 0 .68555.28516l.5625 2.2539h2l.56445-2.2578a5 5 0 0 0 .6875-.2793l1.9902 1.1934 1.4141-1.4141-1.1953-1.9941a5 5 0 0 0 .28516-.68555l2.2539-.5625v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2zm1 5a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/></svg> diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 0c031d7883..bb02d3dc99 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -32,7 +32,7 @@ #define GDSCRIPT_EXTEND_PARSER_H #include "../gdscript_parser.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "lsp.hpp" #ifndef LINE_NUMBER_TO_INDEX diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 2a67d2ff4f..6ddb0d149e 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -30,9 +30,9 @@ #include "gdscript_language_protocol.h" +#include "core/config/project_settings.h" #include "core/io/json.h" #include "core/os/copymem.h" -#include "core/project_settings.h" #include "editor/editor_log.h" #include "editor/editor_node.h" diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index b2fd0c31f9..2a5755bec6 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -31,8 +31,8 @@ #ifndef GDSCRIPT_TEXT_DOCUMENT_H #define GDSCRIPT_TEXT_DOCUMENT_H +#include "core/object/reference.h" #include "core/os/file_access.h" -#include "core/reference.h" #include "lsp.hpp" class GDScriptTextDocument : public Reference { diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 776193e37c..f6643d07f9 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -32,8 +32,8 @@ #include "../gdscript.h" #include "../gdscript_parser.h" -#include "core/project_settings.h" -#include "core/script_language.h" +#include "core/config/project_settings.h" +#include "core/object/script_language.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" #include "editor/editor_node.h" diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index e45b06747d..fc244c6357 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -32,7 +32,7 @@ #define GDSCRIPT_WORKSPACE_H #include "../gdscript_parser.h" -#include "core/variant.h" +#include "core/variant/variant.h" #include "editor/editor_file_system.h" #include "gdscript_extend_parser.h" #include "lsp.hpp" diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index cf27a1578c..bf32c1c978 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -31,8 +31,8 @@ #ifndef GODOT_LSP_H #define GODOT_LSP_H -#include "core/class_db.h" -#include "core/list.h" +#include "core/object/class_db.h" +#include "core/templates/list.h" #include "editor/doc_data.h" namespace lsp { diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index da4cbe34c7..065f01e654 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -59,7 +59,7 @@ GDScriptCache *gdscript_cache = nullptr; #include "editor/gdscript_translation_parser_plugin.h" #ifndef GDSCRIPT_NO_LSP -#include "core/engine.h" +#include "core/config/engine.h" #include "language_server/gdscript_language_server.h" #endif // !GDSCRIPT_NO_LSP diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 68d9984b43..50b3783388 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -30,10 +30,13 @@ #include "test_gdscript.h" +#include "core/config/project_settings.h" +#include "core/io/file_access_pack.h" #include "core/os/file_access.h" #include "core/os/main_loop.h" #include "core/os/os.h" -#include "core/string_builder.h" +#include "core/string/string_builder.h" +#include "scene/resources/packed_scene.h" #include "modules/gdscript/gdscript_analyzer.h" #include "modules/gdscript/gdscript_compiler.h" @@ -179,6 +182,60 @@ static void test_compiler(const String &p_code, const String &p_script_path, con } } +void init_autoloads() { + Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); + + // First pass, add the constants so they exist before any script is loaded. + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->get(); + + if (info.is_singleton) { + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptServer::get_language(i)->add_global_constant(info.name, Variant()); + } + } + } + + // Second pass, load into global constants. + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->get(); + + if (!info.is_singleton) { + // Skip non-singletons since we don't have a scene tree here anyway. + continue; + } + + RES res = ResourceLoader::load(info.path); + ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); + Node *n = nullptr; + if (res->is_class("PackedScene")) { + Ref<PackedScene> ps = res; + n = ps->instance(); + } else if (res->is_class("Script")) { + Ref<Script> script_res = res; + StringName ibt = script_res->get_instance_base_type(); + bool valid_type = ClassDB::is_parent_class(ibt, "Node"); + ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path); + + Object *obj = ClassDB::instance(ibt); + + ERR_CONTINUE_MSG(obj == nullptr, + "Cannot instance script for autoload, expected 'Node' inheritance, got: " + + String(ibt)); + + n = Object::cast_to<Node>(obj); + n->set_script(script_res); + } + + ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path); + n->set_name(info.name); + + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptServer::get_language(i)->add_global_constant(info.name, n); + } + } +} + void test(TestType p_type) { List<String> cmdlargs = OS::get_singleton()->get_cmdline_args(); @@ -195,6 +252,21 @@ void test(TestType p_type) { FileAccessRef fa = FileAccess::open(test, FileAccess::READ); ERR_FAIL_COND_MSG(!fa, "Could not open file: " + test); + // Init PackedData since it's used by ProjectSettings. + PackedData *packed_data = memnew(PackedData); + + // Setup project settings since it's needed by the languages to get the global scripts. + // This also sets up the base resource path. + Error err = ProjectSettings::get_singleton()->setup(fa->get_path_absolute().get_base_dir(), String(), true); + if (err) { + print_line("Could not load project settings."); + // Keep going since some scripts still work without this. + } + + // Initialize the language for the test routine. + ScriptServer::init_languages(); + init_autoloads(); + Vector<uint8_t> buf; int flen = fa->get_len(); buf.resize(fa->get_len() + 1); @@ -226,6 +298,10 @@ void test(TestType p_type) { case TEST_BYTECODE: print_line("Not implemented."); } + + // Destroy stuff we set up earlier. + ScriptServer::finish_languages(); + memdelete(packed_data); } } // namespace TestGDScript |