feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -50,12 +50,12 @@
#include "core/config/project_settings.h"
#include "core/core_constants.h"
#include "core/io/file_access.h"
#include "core/io/file_access_encrypted.h"
#include "core/os/os.h"
#include "scene/resources/packed_scene.h"
#include "scene/scene_string_names.h"
#ifdef TOOLS_ENABLED
#include "core/extension/gdextension_manager.h"
#include "editor/editor_paths.h"
#endif
@ -74,9 +74,16 @@ bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const {
if (ok) {
r_ret = v;
return true;
} else {
return false;
}
MethodBind *method = ClassDB::get_method(name, p_name);
if (method && method->is_static()) {
// Native static method.
r_ret = Callable(this, p_name);
return true;
}
return false;
}
void GDScriptNativeClass::_bind_methods() {
@ -136,7 +143,7 @@ void GDScript::_super_implicit_constructor(GDScript *p_script, GDScriptInstance
}
}
ERR_FAIL_NULL(p_script->implicit_initializer);
if (likely(valid)) {
if (likely(p_script->valid)) {
p_script->implicit_initializer->call(p_instance, nullptr, 0, r_error);
} else {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@ -247,7 +254,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr
bool GDScript::can_instantiate() const {
#ifdef TOOLS_ENABLED
return valid && (tool || ScriptServer::is_scripting_enabled());
return valid && (tool || ScriptServer::is_scripting_enabled()) && !Engine::get_singleton()->is_recovery_mode_hint();
#else
return valid;
#endif
@ -470,23 +477,25 @@ void GDScript::_update_exports_values(HashMap<StringName, Variant> &values, List
}
}
void GDScript::_add_doc(const DocData::ClassDoc &p_inner_class) {
if (_owner) { // Only the top-level class stores doc info
_owner->_add_doc(p_inner_class);
} else { // Remove old docs, add new
void GDScript::_add_doc(const DocData::ClassDoc &p_doc) {
doc_class_name = p_doc.name;
if (_owner) { // Only the top-level class stores doc info.
_owner->_add_doc(p_doc);
} else { // Remove old docs, add new.
for (int i = 0; i < docs.size(); i++) {
if (docs[i].name == p_inner_class.name) {
if (docs[i].name == p_doc.name) {
docs.remove_at(i);
break;
}
}
docs.append(p_inner_class);
docs.append(p_doc);
}
}
void GDScript::_clear_doc() {
docs.clear();
doc_class_name = StringName();
doc = DocData::ClassDoc();
docs.clear();
}
String GDScript::get_class_icon_path() const {
@ -691,10 +700,16 @@ void GDScript::_static_default_init() {
continue;
}
if (type.builtin_type == Variant::ARRAY && type.has_container_element_type(0)) {
const GDScriptDataType element_type = type.get_container_element_type(0);
Array default_value;
const GDScriptDataType &element_type = type.get_container_element_type(0);
default_value.set_typed(element_type.builtin_type, element_type.native_type, element_type.script_type);
static_variables.write[E.value.index] = default_value;
} else if (type.builtin_type == Variant::DICTIONARY && type.has_container_element_types()) {
const GDScriptDataType key_type = type.get_container_element_type_or_variant(0);
const GDScriptDataType value_type = type.get_container_element_type_or_variant(1);
Dictionary default_value;
default_value.set_typed(key_type.builtin_type, key_type.native_type, key_type.script_type, value_type.builtin_type, value_type.native_type, value_type.script_type);
static_variables.write[E.value.index] = default_value;
} else {
Variant default_value;
Callable::CallError err;
@ -878,6 +893,11 @@ Error GDScript::reload(bool p_keep_state) {
if (can_run && p_keep_state) {
_restore_old_static_data();
}
if (p_keep_state) {
// Update the properties in the inspector.
update_exports();
}
#endif
reloading = false;
@ -904,7 +924,7 @@ void GDScript::get_members(HashSet<StringName> *p_members) {
}
}
const Variant GDScript::get_rpc_config() const {
Variant GDScript::get_rpc_config() const {
return rpc_config;
}
@ -952,7 +972,8 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
if (E) {
if (likely(top->valid) && E->value.getter) {
Callable::CallError ce;
r_ret = const_cast<GDScript *>(this)->callp(E->value.getter, nullptr, 0, ce);
const Variant ret = const_cast<GDScript *>(this)->callp(E->value.getter, nullptr, 0, ce);
r_ret = (ce.error == Callable::CallError::CALL_OK) ? ret : Variant();
return true;
}
r_ret = top->static_variables[E->value.index];
@ -1102,7 +1123,7 @@ Error GDScript::load_source_code(const String &p_path) {
w[len] = 0;
String s;
if (s.parse_utf8((const char *)w) != OK) {
if (s.parse_utf8((const char *)w, len) != OK) {
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
@ -1725,10 +1746,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
if (E) {
if (likely(script->valid) && E->value.getter) {
Callable::CallError err;
r_ret = const_cast<GDScriptInstance *>(this)->callp(E->value.getter, nullptr, 0, err);
if (err.error == Callable::CallError::CALL_OK) {
return true;
}
const Variant ret = const_cast<GDScriptInstance *>(this)->callp(E->value.getter, nullptr, 0, err);
r_ret = (err.error == Callable::CallError::CALL_OK) ? ret : Variant();
return true;
}
r_ret = members[E->value.index];
return true;
@ -1750,7 +1770,8 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
if (E) {
if (likely(sptr->valid) && E->value.getter) {
Callable::CallError ce;
r_ret = const_cast<GDScript *>(sptr)->callp(E->value.getter, nullptr, 0, ce);
const Variant ret = const_cast<GDScript *>(sptr)->callp(E->value.getter, nullptr, 0, ce);
r_ret = (ce.error == Callable::CallError::CALL_OK) ? ret : Variant();
return true;
}
r_ret = sptr->static_variables[E->value.index];
@ -1793,7 +1814,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
const Variant *args[1] = { &name };
Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->value)->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err);
Variant ret = E->value->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err);
if (err.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
r_ret = ret;
return true;
@ -1821,14 +1842,14 @@ Variant::Type GDScriptInstance::get_property_type(const StringName &p_name, bool
}
void GDScriptInstance::validate_property(PropertyInfo &p_property) const {
Variant property = (Dictionary)p_property;
const Variant *args[1] = { &property };
const GDScript *sptr = script.ptr();
while (sptr) {
if (likely(sptr->valid)) {
HashMap<StringName, GDScriptFunction *>::ConstIterator E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._validate_property);
if (E) {
Variant property = (Dictionary)p_property;
const Variant *args[1] = { &property };
Callable::CallError err;
Variant ret = E->value->call(const_cast<GDScriptInstance *>(this), args, 1, err);
if (err.error == Callable::CallError::CALL_OK) {
@ -1852,7 +1873,7 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
HashMap<StringName, GDScriptFunction *>::ConstIterator E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list);
if (E) {
Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->value)->call(const_cast<GDScriptInstance *>(this), nullptr, 0, err);
Variant ret = E->value->call(const_cast<GDScriptInstance *>(this), nullptr, 0, err);
if (err.error == Callable::CallError::CALL_OK) {
ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
@ -2176,9 +2197,26 @@ void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_va
global_array.write[globals[p_name]] = p_value;
return;
}
globals[p_name] = global_array.size();
global_array.push_back(p_value);
_global_array = global_array.ptrw();
if (global_array_empty_indexes.size()) {
int index = global_array_empty_indexes[global_array_empty_indexes.size() - 1];
globals[p_name] = index;
global_array.write[index] = p_value;
global_array_empty_indexes.resize(global_array_empty_indexes.size() - 1);
} else {
globals[p_name] = global_array.size();
global_array.push_back(p_value);
_global_array = global_array.ptrw();
}
}
void GDScriptLanguage::_remove_global(const StringName &p_name) {
if (!globals.has(p_name)) {
return;
}
global_array_empty_indexes.push_back(globals[p_name]);
global_array.write[globals[p_name]] = Variant::NIL;
globals.erase(p_name);
}
void GDScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
@ -2236,11 +2274,40 @@ void GDScriptLanguage::init() {
_add_global(E.name, E.ptr);
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
GDExtensionManager::get_singleton()->connect("extension_loaded", callable_mp(this, &GDScriptLanguage::_extension_loaded));
GDExtensionManager::get_singleton()->connect("extension_unloading", callable_mp(this, &GDScriptLanguage::_extension_unloading));
}
#endif
#ifdef TESTS_ENABLED
GDScriptTests::GDScriptTestRunner::handle_cmdline();
#endif
}
#ifdef TOOLS_ENABLED
void GDScriptLanguage::_extension_loaded(const Ref<GDExtension> &p_extension) {
List<StringName> class_list;
ClassDB::get_extension_class_list(p_extension, &class_list);
for (const StringName &n : class_list) {
if (globals.has(n)) {
continue;
}
Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(n));
_add_global(n, nc);
}
}
void GDScriptLanguage::_extension_unloading(const Ref<GDExtension> &p_extension) {
List<StringName> class_list;
ClassDB::get_extension_class_list(p_extension, &class_list);
for (const StringName &n : class_list) {
_remove_global(n);
}
}
#endif
String GDScriptLanguage::get_type() const {
return "GDScript";
}
@ -2486,11 +2553,11 @@ void GDScriptLanguage::reload_all_scripts() {
}
}
}
#endif
#endif // TOOLS_ENABLED
}
reload_scripts(scripts, true);
#endif
#endif // DEBUG_ENABLED
}
void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload) {
@ -2503,7 +2570,7 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload
SelfList<GDScript> *elem = script_list.first();
while (elem) {
// Scripts will reload all subclasses, so only reload root scripts.
if (elem->self()->is_root_script() && elem->self()->get_path().is_resource_file()) {
if (elem->self()->is_root_script() && !elem->self()->get_path().is_empty()) {
scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
}
elem = elem->next();
@ -2560,7 +2627,7 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload
}
}
#endif
#endif // TOOLS_ENABLED
for (const KeyValue<ObjectID, List<Pair<StringName, Variant>>> &F : scr->pending_reload_state) {
map[F.key] = F.value; //pending to reload, use this one instead
@ -2571,7 +2638,19 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload
for (KeyValue<Ref<GDScript>, HashMap<ObjectID, List<Pair<StringName, Variant>>>> &E : to_reload) {
Ref<GDScript> scr = E.key;
print_verbose("GDScript: Reloading: " + scr->get_path());
scr->load_source_code(scr->get_path());
if (scr->is_built_in()) {
// TODO: It would be nice to do it more efficiently than loading the whole scene again.
Ref<PackedScene> scene = ResourceLoader::load(scr->get_path().get_slice("::", 0), "", ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP);
ERR_CONTINUE(scene.is_null());
Ref<SceneState> state = scene->get_state();
Ref<GDScript> fresh = state->get_sub_resource(scr->get_path());
ERR_CONTINUE(fresh.is_null());
scr->set_source_code(fresh->get_source_code());
} else {
scr->load_source_code(scr->get_path());
}
scr->reload(p_soft_reload);
//restore state if saved
@ -2616,7 +2695,7 @@ void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload
//if instance states were saved, set them!
}
#endif
#endif // DEBUG_ENABLED
}
void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
@ -2626,8 +2705,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
}
void GDScriptLanguage::frame() {
calls = 0;
#ifdef DEBUG_ENABLED
if (profiling) {
MutexLock lock(mutex);
@ -2734,7 +2811,7 @@ bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
return p_type == "GDScript";
}
String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path, bool *r_is_abstract, bool *r_is_tool) const {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
@ -2835,13 +2912,18 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
if (r_icon_path) {
*r_icon_path = c->simplified_icon_path;
}
if (r_is_abstract) {
*r_is_abstract = false;
}
if (r_is_tool) {
*r_is_tool = parser.is_tool();
}
return c->identifier != nullptr ? String(c->identifier->name) : String();
}
thread_local GDScriptLanguage::CallStack GDScriptLanguage::_call_stack;
GDScriptLanguage::GDScriptLanguage() {
calls = 0;
ERR_FAIL_COND(singleton);
singleton = this;
strings._init = StaticCString::create("_init");
@ -2857,8 +2939,11 @@ GDScriptLanguage::GDScriptLanguage() {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
#ifdef DEBUG_ENABLED
profiling = false;
profile_native_calls = false;
script_frame_time = 0;
#endif
int dmcs = GLOBAL_DEF(PropertyInfo(Variant::INT, "debug/settings/gdscript/max_call_stack", PROPERTY_HINT_RANGE, "512," + itos(GDScriptFunction::MAX_CALL_DEPTH - 1) + ",1"), 1024);
@ -2873,6 +2958,7 @@ GDScriptLanguage::GDScriptLanguage() {
#ifdef DEBUG_ENABLED
GLOBAL_DEF("debug/gdscript/warnings/enable", true);
GLOBAL_DEF("debug/gdscript/warnings/exclude_addons", true);
GLOBAL_DEF("debug/gdscript/warnings/renamed_in_godot_4_hint", true);
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
GDScriptWarning::Code code = (GDScriptWarning::Code)i;
Variant default_enabled = GDScriptWarning::get_default_value(code);