Merge pull request #57212 from akien-mga/3.x-cherrypicks

This commit is contained in:
Rémi Verschelde 2022-01-25 19:05:13 +01:00 committed by GitHub
commit e17af68daa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 3667 additions and 56 deletions

View file

@ -474,7 +474,7 @@ Variant Array::max() const {
}
const void *Array::id() const {
return _p->array.ptr();
return _p;
}
Array::Array(const Array &p_from) {

View file

@ -280,7 +280,7 @@ void Dictionary::operator=(const Dictionary &p_dictionary) {
}
const void *Dictionary::id() const {
return _p->variant_map.id();
return _p;
}
Dictionary::Dictionary(const Dictionary &p_from) {

View file

@ -611,7 +611,7 @@ Error HTTPClient::poll() {
return OK;
}
int HTTPClient::get_response_body_length() const {
int64_t HTTPClient::get_response_body_length() const {
return body_size;
}

View file

@ -220,7 +220,7 @@ public:
bool is_response_chunked() const;
int get_response_code() const;
Error get_response_headers(List<String> *r_response);
int get_response_body_length() const;
int64_t get_response_body_length() const;
PoolByteArray read_response_body_chunk(); // Can't get body as partial text because of most encodings UTF8, gzip, etc.

View file

@ -11,17 +11,6 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<methods>
<method name="get_mix_mode" qualifiers="const">
<return type="int" enum="AnimationNodeOneShot.MixMode" />
<description>
</description>
</method>
<method name="set_mix_mode">
<return type="void" />
<argument index="0" name="mode" type="int" enum="AnimationNodeOneShot.MixMode" />
<description>
</description>
</method>
</methods>
<members>
<member name="autorestart" type="bool" setter="set_autorestart" getter="has_autorestart" default="false">
@ -37,6 +26,8 @@
</member>
<member name="fadeout_time" type="float" setter="set_fadeout_time" getter="get_fadeout_time" default="0.1">
</member>
<member name="mix_mode" type="int" setter="set_mix_mode" getter="get_mix_mode" enum="AnimationNodeOneShot.MixMode" default="0">
</member>
<member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
</member>
</members>

View file

@ -9,6 +9,12 @@
<tutorials>
</tutorials>
<methods>
<method name="convert_to_image" qualifiers="const">
<return type="Image" />
<description>
Returns an image of the same size as the bitmap and with a [enum Image.Format] of type [code]FORMAT_L8[/code]. [code]true[/code] bits of the bitmap are being converted into white pixels, and [code]false[/code] bits into black.
</description>
</method>
<method name="create">
<return type="void" />
<argument index="0" name="size" type="Vector2" />
@ -58,6 +64,13 @@
<description>
</description>
</method>
<method name="resize">
<return type="void" />
<argument index="0" name="new_size" type="Vector2" />
<description>
Resizes the image to [code]new_size[/code].
</description>
</method>
<method name="set_bit">
<return type="void" />
<argument index="0" name="position" type="Vector2" />

View file

@ -32,7 +32,7 @@
<argument index="0" name="parent" type="Object" default="null" />
<argument index="1" name="idx" type="int" default="-1" />
<description>
Creates an item in the tree and adds it as a child of [code]parent[/code].
Creates an item in the tree and adds it as a child of [code]parent[/code], which can be either a valid [TreeItem] or [code]null[/code].
If [code]parent[/code] is [code]null[/code], the root item will be the parent, or the new item will be the root itself if the tree is empty.
The new item will be the [code]idx[/code]th child of parent, or it will be the last child if there are not enough siblings.
</description>
@ -111,7 +111,7 @@
<argument index="0" name="item" type="Object" />
<argument index="1" name="column" type="int" default="-1" />
<description>
Returns the rectangle area for the specified item. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
Returns the rectangle area for the specified [TreeItem]. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
</description>
</method>
<method name="get_item_at_position" qualifiers="const">
@ -125,7 +125,7 @@
<return type="TreeItem" />
<argument index="0" name="from" type="Object" />
<description>
Returns the next selected item after the given one, or [code]null[/code] if the end is reached.
Returns the next selected [TreeItem] after the given one, or [code]null[/code] if the end is reached.
If [code]from[/code] is [code]null[/code], this returns the first selected item.
</description>
</method>
@ -167,7 +167,7 @@
<return type="void" />
<argument index="0" name="item" type="Object" />
<description>
Causes the [Tree] to jump to the specified item.
Causes the [Tree] to jump to the specified [TreeItem].
</description>
</method>
<method name="set_column_expand">

View file

@ -915,6 +915,9 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
}
void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) {
if (le == nullptr) {
return; // The text_submitted signal triggered the graph update and freed the LineEdit.
}
_node_renamed(le->call("get_text"), p_node);
}

View file

@ -616,6 +616,7 @@ void EditorAssetLibrary::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_update_repository_options();
setup_http_request(request);
} break;
}
}

View file

@ -822,19 +822,30 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
for (int i = 0; i < frames->get_frame_count(edited_anim); i++) {
String name;
Ref<Texture> icon;
Ref<Texture> frame = frames->get_frame(edited_anim, i);
if (frames->get_frame(edited_anim, i).is_null()) {
if (frame.is_null()) {
name = itos(i) + ": " + TTR("(empty)");
} else {
name = itos(i) + ": " + frames->get_frame(edited_anim, i)->get_name();
icon = frames->get_frame(edited_anim, i);
name = itos(i) + ": " + frame->get_name();
}
tree->add_item(name, icon);
if (frames->get_frame(edited_anim, i).is_valid()) {
tree->set_item_tooltip(tree->get_item_count() - 1, frames->get_frame(edited_anim, i)->get_path());
tree->add_item(name, frame);
if (frame.is_valid()) {
String tooltip = frame->get_path();
// Frame is often saved as an AtlasTexture subresource within a scene/resource file,
// thus its path might be not what the user is looking for. So we're also showing
// subsequent source texture paths.
String prefix = String::utf8("┖╴");
Ref<AtlasTexture> at = frame;
while (at.is_valid() && at->get_atlas().is_valid()) {
tooltip += "\n" + prefix + at->get_atlas()->get_path();
prefix = " " + prefix;
at = at->get_atlas();
}
tree->set_item_tooltip(tree->get_item_count() - 1, tooltip);
}
if (sel == i) {
tree->select(tree->get_item_count() - 1);

View file

@ -284,6 +284,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
vbc->add_child(lbl_preview_title);
lbl_preview = memnew(Label);
lbl_preview->set_autowrap(true);
vbc->add_child(lbl_preview);
// ---- Dialog related

View file

@ -9,8 +9,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="application-name" content="Godot" />
<meta name="apple-mobile-web-app-title" content="Godot" />
<meta name="theme-color" content="#478cbf" />
<meta name="msapplication-navbutton-color" content="#478cbf" />
<meta name="theme-color" content="#202531" />
<meta name="msapplication-navbutton-color" content="#202531" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="msapplication-starturl" content="/latest" />
<meta property="og:site_name" content="Godot Engine Web Editor" />

View file

@ -6,7 +6,7 @@
"start_url": "./godot.tools.html",
"display": "standalone",
"orientation": "landscape",
"theme_color": "#478cbf",
"theme_color": "#202531",
"icons": [
{
"src": "favicon.png",

View file

@ -4,6 +4,8 @@
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#202531" />
<meta name="msapplication-navbutton-color" content="#202531" />
<title>You are offline</title>
<style>
html {

View file

@ -88,10 +88,10 @@ def configure(env):
if env["tools"]:
if not env["threads_enabled"]:
print("Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option")
sys.exit(255)
print('Note: Forcing "threads_enabled=yes" as it is required for the web editor.')
env["threads_enabled"] = "yes"
if env["initial_memory"] < 64:
print("Editor build requires at least 64MiB of initial memory. Forcing it.")
print('Note: Forcing "initial_memory=64" as it is required for the web editor.')
env["initial_memory"] = 64
else:
# Disable exceptions and rtti on non-tools (template) builds

View file

@ -185,7 +185,7 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {
return OK;
}
int HTTPClient::get_response_body_length() const {
int64_t HTTPClient::get_response_body_length() const {
return godot_js_fetch_body_length_get(js_id);
}

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,8 @@
"name": "godot",
"private": true,
"version": "1.0.0",
"description": "Linting setup for Godot's HTML5 platform code",
"description": "Development and linting setup for Godot's HTML5 platform code",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"docs": "jsdoc --template js/jsdoc2rst/ js/engine/engine.js js/engine/config.js --destination ''",
"lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules && npm run lint:tools",
"lint:engine": "eslint \"js/engine/*.js\" --no-eslintrc -c .eslintrc.engine.js",
@ -15,7 +14,8 @@
"format:engine": "npm run lint:engine -- --fix",
"format:libs": "npm run lint:libs -- --fix",
"format:modules": "npm run lint:modules -- --fix",
"format:tools": "npm run lint:tools -- --fix"
"format:tools": "npm run lint:tools -- --fix",
"serve": "serve"
},
"author": "Godot Engine contributors",
"license": "MIT",
@ -23,6 +23,7 @@
"eslint": "^7.28.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.23.4",
"jsdoc": "^3.6.7"
"jsdoc": "^3.6.7",
"serve": "^13.0.2"
}
}

View file

@ -0,0 +1,21 @@
{
"public": "../../bin",
"headers": [{
"source": "**/*",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "require-corp"
}, {
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}, {
"key": "Access-Control-Allow-Origin",
"value": "*"
}, {
"key": "Cache-Control",
"value": "no-store, max-age=0"
}
]
}]
}

View file

@ -3887,7 +3887,7 @@ Error OS_X11::move_to_trash(const String &p_path) {
// Create needed directories for decided trash can location.
{
DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = dir_access->make_dir_recursive(trash_path);
// Issue an error if trash can is not created proprely.
@ -3896,7 +3896,6 @@ Error OS_X11::move_to_trash(const String &p_path) {
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/files");
err = dir_access->make_dir_recursive(trash_path + "/info");
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/info");
memdelete(dir_access);
}
// The trash can is successfully created, now we check that we don't exceed our file name length limit.
@ -3936,16 +3935,15 @@ Error OS_X11::move_to_trash(const String &p_path) {
String trash_info = "[Trash Info]\nPath=" + p_path.http_escape() + "\nDeletionDate=" + timestamp + "\n";
{
Error err;
FileAccess *file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
FileAccessRef file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Can't create trashinfo file:" + trash_path + "/info/" + file_name + ".trashinfo");
file->store_string(trash_info);
file->close();
// Rename our resource before moving it to the trash can.
DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
err = dir_access->rename(p_path, p_path.get_base_dir() + "/" + file_name);
ERR_FAIL_COND_V_MSG(err != OK, err, "Can't rename file \"" + p_path + "\"");
memdelete(dir_access);
}
// Move the given resource to the trash can.

View file

@ -321,6 +321,8 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeOneShot::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeOneShot::is_using_sync);
ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_mode", PROPERTY_HINT_ENUM, "Blend,Add"), "set_mix_mode", "get_mix_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time");

View file

@ -1303,12 +1303,14 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
Node *Node::get_node(const NodePath &p_path) const {
Node *node = get_node_or_null(p_path);
if (p_path.is_absolute()) {
ERR_FAIL_COND_V_MSG(!node, nullptr,
vformat("(Node not found: \"%s\" (absolute path attempted from \"%s\").)", p_path, get_path()));
} else {
ERR_FAIL_COND_V_MSG(!node, nullptr,
vformat("(Node not found: \"%s\" (relative to \"%s\").)", p_path, get_path()));
if (unlikely(!node)) {
if (p_path.is_absolute()) {
ERR_FAIL_V_MSG(nullptr,
vformat("(Node not found: \"%s\" (absolute path attempted from \"%s\").)", p_path, get_path()));
} else {
ERR_FAIL_V_MSG(nullptr,
vformat("(Node not found: \"%s\" (relative to \"%s\").)", p_path, get_path()));
}
}
return node;

View file

@ -668,11 +668,13 @@ void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_true_bit_count"), &BitMap::get_true_bit_count);
ClassDB::bind_method(D_METHOD("get_size"), &BitMap::get_size);
ClassDB::bind_method(D_METHOD("resize", "new_size"), &BitMap::resize);
ClassDB::bind_method(D_METHOD("_set_data"), &BitMap::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &BitMap::_get_data);
ClassDB::bind_method(D_METHOD("grow_mask", "pixels", "rect"), &BitMap::grow_mask);
ClassDB::bind_method(D_METHOD("convert_to_image"), &BitMap::convert_to_image);
ClassDB::bind_method(D_METHOD("opaque_to_polygons", "rect", "epsilon"), &BitMap::_opaque_to_polygons_bind, DEFVAL(2.0));
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");

View file

@ -30,6 +30,8 @@
#include "mesh_library.h"
#include "box_shape.h"
bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
if (name.begins_with("item/")) {
@ -254,12 +256,35 @@ int MeshLibrary::get_last_unused_item_id() const {
}
void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
ERR_FAIL_COND(p_shapes.size() & 1);
Array arr_shapes = p_shapes;
int size = p_shapes.size();
if (size & 1) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
int prev_size = item_map[p_item].shapes.size() * 2;
if (prev_size < size) {
// Check if last element is a shape.
Ref<Shape> shape = arr_shapes[size - 1];
if (shape.is_null()) {
Ref<BoxShape> box_shape;
box_shape.instance();
arr_shapes[size - 1] = box_shape;
}
// Make sure the added element is a Transform.
arr_shapes.push_back(Transform());
size++;
} else {
size--;
arr_shapes.resize(size);
}
}
Vector<ShapeData> shapes;
for (int i = 0; i < p_shapes.size(); i += 2) {
for (int i = 0; i < size; i += 2) {
ShapeData sd;
sd.shape = p_shapes[i + 0];
sd.local_transform = p_shapes[i + 1];
sd.shape = arr_shapes[i + 0];
sd.local_transform = arr_shapes[i + 1];
if (sd.shape.is_valid()) {
shapes.push_back(sd);