feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue