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

Cherry-picks for the 3.x branch (future 3.4) - 4th batch
This commit is contained in:
Rémi Verschelde 2021-05-21 19:05:17 +02:00 committed by GitHub
commit 7cd5967e99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 242 additions and 134 deletions

View File

@ -132,7 +132,7 @@ void XMLParser::_parse_closing_xml_element() {
++P; ++P;
const char *pBeginClose = P; const char *pBeginClose = P;
while (*P != '>') { while (*P && *P != '>') {
++P; ++P;
} }
@ -140,7 +140,10 @@ void XMLParser::_parse_closing_xml_element() {
#ifdef DEBUG_XML #ifdef DEBUG_XML
print_line("XML CLOSE: " + node_name); print_line("XML CLOSE: " + node_name);
#endif #endif
++P;
if (*P) {
++P;
}
} }
void XMLParser::_ignore_definition() { void XMLParser::_ignore_definition() {
@ -148,11 +151,14 @@ void XMLParser::_ignore_definition() {
char *F = P; char *F = P;
// move until end marked with '>' reached // move until end marked with '>' reached
while (*P != '>') { while (*P && *P != '>') {
++P; ++P;
} }
node_name.parse_utf8(F, P - F); node_name.parse_utf8(F, P - F);
++P;
if (*P) {
++P;
}
} }
bool XMLParser::_parse_cdata() { bool XMLParser::_parse_cdata() {
@ -170,6 +176,7 @@ bool XMLParser::_parse_cdata() {
} }
if (!*P) { if (!*P) {
node_name = "";
return true; return true;
} }
@ -188,10 +195,9 @@ bool XMLParser::_parse_cdata() {
} }
if (cDataEnd) { if (cDataEnd) {
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); cDataEnd = P;
} else {
node_name = "";
} }
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
#ifdef DEBUG_XML #ifdef DEBUG_XML
print_line("XML CDATA: " + node_name); print_line("XML CDATA: " + node_name);
#endif #endif
@ -203,24 +209,45 @@ void XMLParser::_parse_comment() {
node_type = NODE_COMMENT; node_type = NODE_COMMENT;
P += 1; P += 1;
char *pCommentBegin = P; char *pEndOfInput = data + length;
char *pCommentBegin;
char *pCommentEnd;
int count = 1; if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') {
// Comment, use '-->' as end.
pCommentBegin = P + 2;
for (pCommentEnd = pCommentBegin; pCommentEnd + 2 < pEndOfInput; pCommentEnd++) {
if (pCommentEnd[0] == '-' && pCommentEnd[1] == '-' && pCommentEnd[2] == '>') {
break;
}
}
if (pCommentEnd + 2 < pEndOfInput) {
P = pCommentEnd + 3;
} else {
P = pCommentEnd = pEndOfInput;
}
} else {
// Like document type definition, match angle brackets.
pCommentBegin = P;
// move until end of comment reached int count = 1;
while (count) { while (*P && count) {
if (*P == '>') { if (*P == '>') {
--count; --count;
} else if (*P == '<') { } else if (*P == '<') {
++count; ++count;
}
++P;
} }
++P; if (count) {
pCommentEnd = P;
} else {
pCommentEnd = P - 1;
}
} }
P -= 3; node_name = String::utf8(pCommentBegin, (int)(pCommentEnd - pCommentBegin));
node_name = String::utf8(pCommentBegin + 2, (int)(P - pCommentBegin - 2));
P += 3;
#ifdef DEBUG_XML #ifdef DEBUG_XML
print_line("XML COMMENT: " + node_name); print_line("XML COMMENT: " + node_name);
#endif #endif
@ -235,14 +262,14 @@ void XMLParser::_parse_opening_xml_element() {
const char *startName = P; const char *startName = P;
// find end of element // find end of element
while (*P != '>' && !_is_white_space(*P)) { while (*P && *P != '>' && !_is_white_space(*P)) {
++P; ++P;
} }
const char *endName = P; const char *endName = P;
// find attributes // find attributes
while (*P != '>') { while (*P && *P != '>') {
if (_is_white_space(*P)) { if (_is_white_space(*P)) {
++P; ++P;
} else { } else {
@ -252,10 +279,14 @@ void XMLParser::_parse_opening_xml_element() {
// read the attribute names // read the attribute names
const char *attributeNameBegin = P; const char *attributeNameBegin = P;
while (!_is_white_space(*P) && *P != '=') { while (*P && !_is_white_space(*P) && *P != '=') {
++P; ++P;
} }
if (!*P) {
break;
}
const char *attributeNameEnd = P; const char *attributeNameEnd = P;
++P; ++P;
@ -266,7 +297,7 @@ void XMLParser::_parse_opening_xml_element() {
} }
if (!*P) { // malformatted xml file if (!*P) { // malformatted xml file
return; break;
} }
const char attributeQuoteChar = *P; const char attributeQuoteChar = *P;
@ -278,12 +309,10 @@ void XMLParser::_parse_opening_xml_element() {
++P; ++P;
} }
if (!*P) { // malformatted xml file
return;
}
const char *attributeValueEnd = P; const char *attributeValueEnd = P;
++P; if (*P) {
++P;
}
Attribute attr; Attribute attr;
attr.name = String::utf8(attributeNameBegin, attr.name = String::utf8(attributeNameBegin,
@ -315,7 +344,9 @@ void XMLParser::_parse_opening_xml_element() {
print_line("XML OPEN: " + node_name); print_line("XML OPEN: " + node_name);
#endif #endif
++P; if (*P) {
++P;
}
} }
void XMLParser::_parse_current_node() { void XMLParser::_parse_current_node() {
@ -327,10 +358,6 @@ void XMLParser::_parse_current_node() {
++P; ++P;
} }
if (!*P) {
return;
}
if (P - start > 0) { if (P - start > 0) {
// we found some text, store it // we found some text, store it
if (_set_text(start, P)) { if (_set_text(start, P)) {
@ -338,6 +365,10 @@ void XMLParser::_parse_current_node() {
} }
} }
if (!*P) {
return;
}
++P; ++P;
// based on current token, parse and report next element // based on current token, parse and report next element

View File

@ -255,8 +255,8 @@ public:
static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); } static _ALWAYS_INLINE_ double db2linear(double p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); } static _ALWAYS_INLINE_ float db2linear(float p_db) { return Math::exp(p_db * 0.11512925464970228420089957273422); }
static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } static _ALWAYS_INLINE_ double round(double p_val) { return ::round(p_val); }
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } static _ALWAYS_INLINE_ float round(float p_val) { return ::roundf(p_val); }
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) { static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
int64_t range = max - min; int64_t range = max - min;
@ -376,28 +376,10 @@ public:
return u.d; return u.d;
} }
//this function should be as fast as possible and rounding mode should not matter // This function should be as fast as possible and rounding mode should not matter.
static _ALWAYS_INLINE_ int fast_ftoi(float a) { static _ALWAYS_INLINE_ int fast_ftoi(float a) {
static int b; // Assuming every supported compiler has `lrint()`.
return lrintf(a);
#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone?
b = (int)((a > 0.0) ? (a + 0.5) : (a - 0.5));
#elif defined(_MSC_VER) && _MSC_VER < 1800
__asm fld a __asm fistp b
/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
// use AT&T inline assembly style, document that
// we use memory as output (=m) and input (m)
__asm__ __volatile__ (
"flds %1 \n\t"
"fistpl %0 \n\t"
: "=m" (b)
: "m" (a));*/
#else
b = lrintf(a); //assuming everything but msvc 2012 or earlier has lrint
#endif
return b;
} }
static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) { static _ALWAYS_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) {

View File

@ -65,8 +65,8 @@ public:
bool _set(const StringName &p_name, const Variant &p_value) { bool _set(const StringName &p_name, const Variant &p_value) {
String name = p_name; String name = p_name;
if (name.begins_with("bind/")) { if (name.begins_with("bind/argument_")) {
int which = name.get_slice("/", 1).to_int() - 1; int which = name.get_slice("_", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false); ERR_FAIL_INDEX_V(which, params.size(), false);
params.write[which] = p_value; params.write[which] = p_value;
} else { } else {
@ -79,8 +79,8 @@ public:
bool _get(const StringName &p_name, Variant &r_ret) const { bool _get(const StringName &p_name, Variant &r_ret) const {
String name = p_name; String name = p_name;
if (name.begins_with("bind/")) { if (name.begins_with("bind/argument_")) {
int which = name.get_slice("/", 1).to_int() - 1; int which = name.get_slice("_", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false); ERR_FAIL_INDEX_V(which, params.size(), false);
r_ret = params[which]; r_ret = params[which];
} else { } else {
@ -92,7 +92,7 @@ public:
void _get_property_list(List<PropertyInfo> *p_list) const { void _get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < params.size(); i++) { for (int i = 0; i < params.size(); i++) {
p_list->push_back(PropertyInfo(params[i].get_type(), "bind/" + itos(i + 1))); p_list->push_back(PropertyInfo(params[i].get_type(), "bind/argument_" + itos(i + 1)));
} }
} }

View File

@ -613,23 +613,35 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
return res; return res;
} }
// signatures // Different metrics may contain different number of categories.
Vector<String> signatures; Set<StringName> possible_signatures;
const Vector<EditorProfiler::Metric::Category> &categories = frame_metrics[0].categories; for (int i = 0; i < frame_metrics.size(); i++) {
const Metric &m = frame_metrics[i];
for (int j = 0; j < categories.size(); j++) { if (!m.valid) {
const EditorProfiler::Metric::Category &c = categories[j]; continue;
signatures.push_back(c.signature);
for (int k = 0; k < c.items.size(); k++) {
signatures.push_back(c.items[k].signature);
} }
for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) {
possible_signatures.insert(E->key());
}
for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) {
possible_signatures.insert(E->key());
}
}
// Generate CSV header and cache indices.
Map<StringName, int> sig_map;
Vector<String> signatures;
signatures.resize(possible_signatures.size());
int sig_index = 0;
for (const Set<StringName>::Element *E = possible_signatures.front(); E; E = E->next()) {
signatures.write[sig_index] = E->get();
sig_map[E->get()] = sig_index;
sig_index++;
} }
res.push_back(signatures); res.push_back(signatures);
// values // values
Vector<String> values; Vector<String> values;
values.resize(signatures.size());
int index = last_metric; int index = last_metric;
@ -640,20 +652,23 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
index = 0; index = 0;
} }
if (!frame_metrics[index].valid) { const Metric &m = frame_metrics[index];
if (!m.valid) {
continue; continue;
} }
int it = 0;
const Vector<EditorProfiler::Metric::Category> &frame_cat = frame_metrics[index].categories;
for (int j = 0; j < frame_cat.size(); j++) { // Don't keep old values since there may be empty cells.
const EditorProfiler::Metric::Category &c = frame_cat[j]; values.clear();
values.write[it++] = String::num_real(c.total_time); values.resize(possible_signatures.size());
for (int k = 0; k < c.items.size(); k++) { for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) {
values.write[it++] = String::num_real(c.items[k].total); values.write[sig_map[E->key()]] = String::num_real(E->value()->total_time);
}
} }
for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) {
values.write[sig_map[E->key()]] = String::num_real(E->value()->total);
}
res.push_back(values); res.push_back(values);
} }

View File

@ -707,8 +707,10 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
match_rect.position.y += 1 * EDSCALE; match_rect.position.y += 1 * EDSCALE;
match_rect.size.y -= 2 * EDSCALE; match_rect.size.y -= 2 * EDSCALE;
_results_display->draw_rect(match_rect, Color(0, 0, 0, 0.5)); // Use the inverted accent color to help match rectangles stand out even on the currently selected line.
// Text is drawn by Tree already _results_display->draw_rect(match_rect, get_color("accent_color", "Editor").inverted() * Color(1, 1, 1, 0.5));
// Text is drawn by Tree already.
} }
void FindInFilesPanel::_on_item_edited() { void FindInFilesPanel::_on_item_edited() {

View File

@ -1451,8 +1451,11 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
} }
} }
ERR_FAIL_COND_V_MSG(img.is_null(), ERR_FILE_CORRUPT, if (img.is_null()) {
vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype)); ERR_PRINT(vformat("glTF: Couldn't load image index '%d' with its given mimetype: %s.", i, mimetype));
state.images.push_back(Ref<Texture>());
continue;
}
Ref<ImageTexture> t; Ref<ImageTexture> t;
t.instance(); t.instance();
@ -2356,6 +2359,9 @@ bool EditorSceneImporterGLTF::_skins_are_same(const Ref<Skin> &skin_a, const Ref
if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) { if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
return false; return false;
} }
if (skin_a->get_bind_name(i) != skin_b->get_bind_name(i)) {
return false;
}
Transform a_xform = skin_a->get_bind_pose(i); Transform a_xform = skin_a->get_bind_pose(i);
Transform b_xform = skin_b->get_bind_pose(i); Transform b_xform = skin_b->get_bind_pose(i);
@ -3135,13 +3141,15 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial
const GLTFSkinIndex skin_i = node->skin; const GLTFSkinIndex skin_i = node->skin;
Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i); Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
ERR_CONTINUE_MSG(mi_element == nullptr, vformat("Unable to find node %d", node_i));
MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get()); MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
ERR_FAIL_COND(mi == nullptr); ERR_CONTINUE_MSG(mi == nullptr, vformat("Unable to cast node %d of type %s to MeshInstance", node_i, mi_element->get()->get_class_name()));
const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton; const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i]; const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i];
Skeleton *skeleton = gltf_skeleton.godot_skeleton; Skeleton *skeleton = gltf_skeleton.godot_skeleton;
ERR_FAIL_COND(skeleton == nullptr); ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i));
mi->get_parent()->remove_child(mi); mi->get_parent()->remove_child(mi);
skeleton->add_child(mi); skeleton->add_child(mi);

View File

@ -80,10 +80,10 @@ void ViewportRotationControl::_notification(int p_what) {
axis_menu_options.clear(); axis_menu_options.clear();
axis_menu_options.push_back(SpatialEditorViewport::VIEW_RIGHT); axis_menu_options.push_back(SpatialEditorViewport::VIEW_RIGHT);
axis_menu_options.push_back(SpatialEditorViewport::VIEW_TOP); axis_menu_options.push_back(SpatialEditorViewport::VIEW_TOP);
axis_menu_options.push_back(SpatialEditorViewport::VIEW_FRONT); axis_menu_options.push_back(SpatialEditorViewport::VIEW_REAR);
axis_menu_options.push_back(SpatialEditorViewport::VIEW_LEFT); axis_menu_options.push_back(SpatialEditorViewport::VIEW_LEFT);
axis_menu_options.push_back(SpatialEditorViewport::VIEW_BOTTOM); axis_menu_options.push_back(SpatialEditorViewport::VIEW_BOTTOM);
axis_menu_options.push_back(SpatialEditorViewport::VIEW_REAR); axis_menu_options.push_back(SpatialEditorViewport::VIEW_FRONT);
axis_colors.clear(); axis_colors.clear();
axis_colors.push_back(get_color("axis_x_color", "Editor")); axis_colors.push_back(get_color("axis_x_color", "Editor"));

12
misc/dist/osx/editor.entitlements vendored Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

18
misc/dist/osx/editor_mono.entitlements vendored Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>

View File

@ -2238,31 +2238,45 @@ MainLoop *OS_OSX::get_main_loop() const {
} }
String OS_OSX::get_config_path() const { String OS_OSX::get_config_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CONFIG_HOME")) { if (has_environment("XDG_CONFIG_HOME")) {
return get_environment("XDG_CONFIG_HOME"); if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
} else if (has_environment("HOME")) { return get_environment("XDG_CONFIG_HOME");
return get_environment("HOME").plus_file("Library/Application Support"); } else {
} else { WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Library/Application Support` or `.` per the XDG Base Directory specification.");
return "."; }
} }
if (has_environment("HOME")) {
return get_environment("HOME").plus_file("Library/Application Support");
}
return ".";
} }
String OS_OSX::get_data_path() const { String OS_OSX::get_data_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_DATA_HOME")) { if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME"); if (get_environment("XDG_DATA_HOME").is_abs_path()) {
} else { return get_environment("XDG_DATA_HOME");
return get_config_path(); } else {
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
}
} }
return get_config_path();
} }
String OS_OSX::get_cache_path() const { String OS_OSX::get_cache_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well.
if (has_environment("XDG_CACHE_HOME")) { if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME"); if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
} else if (has_environment("HOME")) { return get_environment("XDG_CACHE_HOME");
return get_environment("HOME").plus_file("Library/Caches"); } else {
} else { WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/Libary/Caches` or `get_config_path()` per the XDG Base Directory specification.");
return get_config_path(); }
} }
if (has_environment("HOME")) {
return get_environment("HOME").plus_file("Library/Caches");
}
return get_config_path();
} }
String OS_OSX::get_bundle_resource_dir() const { String OS_OSX::get_bundle_resource_dir() const {

View File

@ -3316,31 +3316,45 @@ MainLoop *OS_Windows::get_main_loop() const {
} }
String OS_Windows::get_config_path() const { String OS_Windows::get_config_path() const {
if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not? // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
return get_environment("XDG_CONFIG_HOME"); if (has_environment("XDG_CONFIG_HOME")) {
} else if (has_environment("APPDATA")) { if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
return get_environment("APPDATA"); return get_environment("XDG_CONFIG_HOME");
} else { } else {
return "."; WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification.");
}
} }
if (has_environment("APPDATA")) {
return get_environment("APPDATA");
}
return ".";
} }
String OS_Windows::get_data_path() const { String OS_Windows::get_data_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
if (has_environment("XDG_DATA_HOME")) { if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME"); if (get_environment("XDG_DATA_HOME").is_abs_path()) {
} else { return get_environment("XDG_DATA_HOME");
return get_config_path(); } else {
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification.");
}
} }
return get_config_path();
} }
String OS_Windows::get_cache_path() const { String OS_Windows::get_cache_path() const {
// The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well.
if (has_environment("XDG_CACHE_HOME")) { if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME"); if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
} else if (has_environment("TEMP")) { return get_environment("XDG_CACHE_HOME");
return get_environment("TEMP"); } else {
} else { WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification.");
return get_config_path(); }
} }
if (has_environment("TEMP")) {
return get_environment("TEMP");
}
return get_config_path();
} }
// Get properly capitalized engine name for system paths // Get properly capitalized engine name for system paths

View File

@ -3208,32 +3208,44 @@ bool OS_X11::_check_internal_feature_support(const String &p_feature) {
String OS_X11::get_config_path() const { String OS_X11::get_config_path() const {
if (has_environment("XDG_CONFIG_HOME")) { if (has_environment("XDG_CONFIG_HOME")) {
return get_environment("XDG_CONFIG_HOME"); if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
} else if (has_environment("HOME")) { return get_environment("XDG_CONFIG_HOME");
return get_environment("HOME").plus_file(".config"); } else {
} else { WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.config` or `.` per the XDG Base Directory specification.");
return "."; }
} }
if (has_environment("HOME")) {
return get_environment("HOME").plus_file(".config");
}
return ".";
} }
String OS_X11::get_data_path() const { String OS_X11::get_data_path() const {
if (has_environment("XDG_DATA_HOME")) { if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME"); if (get_environment("XDG_DATA_HOME").is_abs_path()) {
} else if (has_environment("HOME")) { return get_environment("XDG_DATA_HOME");
return get_environment("HOME").plus_file(".local/share"); } else {
} else { WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.local/share` or `get_config_path()` per the XDG Base Directory specification.");
return get_config_path(); }
} }
if (has_environment("HOME")) {
return get_environment("HOME").plus_file(".local/share");
}
return get_config_path();
} }
String OS_X11::get_cache_path() const { String OS_X11::get_cache_path() const {
if (has_environment("XDG_CACHE_HOME")) { if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME"); if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
} else if (has_environment("HOME")) { return get_environment("XDG_CACHE_HOME");
return get_environment("HOME").plus_file(".cache"); } else {
} else { WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.cache` or `get_config_path()` per the XDG Base Directory specification.");
return get_config_path(); }
} }
if (has_environment("HOME")) {
return get_environment("HOME").plus_file(".cache");
}
return get_config_path();
} }
String OS_X11::get_system_dir(SystemDir p_dir) const { String OS_X11::get_system_dir(SystemDir p_dir) const {

View File

@ -1166,7 +1166,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
newedge.p1 = v->p; newedge.p1 = v->p;
newedge.p2 = v->p; newedge.p2 = v->p;
edgeIter = edgeTree.lower_bound(newedge); edgeIter = edgeTree.lower_bound(newedge);
if(edgeIter == edgeTree.front()) { if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
error = true; error = true;
break; break;
} }
@ -1202,7 +1202,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
newedge.p1 = v->p; newedge.p1 = v->p;
newedge.p2 = v->p; newedge.p2 = v->p;
edgeIter = edgeTree.lower_bound(newedge); edgeIter = edgeTree.lower_bound(newedge);
if(edgeIter == edgeTree.front()) { if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
error = true; error = true;
break; break;
} }
@ -1241,7 +1241,7 @@ int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, Li
newedge.p1 = v->p; newedge.p1 = v->p;
newedge.p2 = v->p; newedge.p2 = v->p;
edgeIter = edgeTree.lower_bound(newedge); edgeIter = edgeTree.lower_bound(newedge);
if(edgeIter == edgeTree.front()) { if(edgeIter == nullptr || edgeIter == edgeTree.front()) {
error = true; error = true;
break; break;
} }