Merge pull request #57491 from akien-mga/3.x-cherrypicks
This commit is contained in:
commit
b7b2fd0634
@ -96,6 +96,11 @@ struct _IP_ResolverPrivate {
|
|||||||
if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) {
|
if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// We might be overriding another result, but we don't care as long as the result is valid.
|
||||||
|
if (response.size()) {
|
||||||
|
String key = get_cache_key(hostname, type);
|
||||||
|
cache[key] = response;
|
||||||
|
}
|
||||||
queue[i].response = response;
|
queue[i].response = response;
|
||||||
queue[i].status.set(response.empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE);
|
queue[i].status.set(response.empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE);
|
||||||
}
|
}
|
||||||
@ -118,30 +123,8 @@ struct _IP_ResolverPrivate {
|
|||||||
};
|
};
|
||||||
|
|
||||||
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
||||||
List<IP_Address> res;
|
const Array addresses = resolve_hostname_addresses(p_hostname, p_type);
|
||||||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
return addresses.size() ? addresses[0].operator IP_Address() : IP_Address();
|
||||||
|
|
||||||
resolver->mutex.lock();
|
|
||||||
if (resolver->cache.has(key)) {
|
|
||||||
res = resolver->cache[key];
|
|
||||||
} else {
|
|
||||||
// This should be run unlocked so the resolver thread can keep
|
|
||||||
// resolving other requests.
|
|
||||||
resolver->mutex.unlock();
|
|
||||||
_resolve_hostname(res, p_hostname, p_type);
|
|
||||||
resolver->mutex.lock();
|
|
||||||
// We might be overriding another result, but we don't care (they are the
|
|
||||||
// same hostname).
|
|
||||||
resolver->cache[key] = res;
|
|
||||||
}
|
|
||||||
resolver->mutex.unlock();
|
|
||||||
|
|
||||||
for (int i = 0; i < res.size(); ++i) {
|
|
||||||
if (res[i].is_valid()) {
|
|
||||||
return res[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return IP_Address();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
|
Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
|
||||||
@ -157,17 +140,16 @@ Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
|
|||||||
resolver->mutex.unlock();
|
resolver->mutex.unlock();
|
||||||
_resolve_hostname(res, p_hostname, p_type);
|
_resolve_hostname(res, p_hostname, p_type);
|
||||||
resolver->mutex.lock();
|
resolver->mutex.lock();
|
||||||
// We might be overriding another result, but we don't care (they are the
|
// We might be overriding another result, but we don't care as long as the result is valid.
|
||||||
// same hostname).
|
if (res.size()) {
|
||||||
resolver->cache[key] = res;
|
resolver->cache[key] = res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resolver->mutex.unlock();
|
resolver->mutex.unlock();
|
||||||
|
|
||||||
Array result;
|
Array result;
|
||||||
for (int i = 0; i < res.size(); ++i) {
|
for (int i = 0; i < res.size(); ++i) {
|
||||||
if (res[i].is_valid()) {
|
result.push_back(String(res[i]));
|
||||||
result.push_back(String(res[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
See also [AudioStreamGenerator] for procedurally generating sounds.
|
See also [AudioStreamGenerator] for procedurally generating sounds.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="https://godotengine.org/asset-library/asset/528">Audio Spectrum Demo</link>
|
<link title="Audio Spectrum Demo">https://godotengine.org/asset-library/asset/528</link>
|
||||||
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
|
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
</methods>
|
</methods>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
|
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
|
||||||
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
|
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
</methods>
|
</methods>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
|
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
|
||||||
<link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
|
<link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="can_push_buffer" qualifiers="const">
|
<method name="can_push_buffer" qualifiers="const">
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
|
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
|
||||||
The maximum distance away from the [ReflectionProbe] an object can be before it is culled. Decrease this to improve performance, especially when using the [constant UPDATE_ALWAYS] [member update_mode].
|
The maximum distance away from the [ReflectionProbe] an object can be before it is culled. Decrease this to improve performance, especially when using the [constant UPDATE_ALWAYS] [member update_mode].
|
||||||
|
[b]Note:[/b] The maximum reflection distance is always at least equal to the [member extents]. This means that decreasing [member max_distance] will not always cull objects from reflections, especially if the reflection probe's [member extents] are already large.
|
||||||
</member>
|
</member>
|
||||||
<member name="origin_offset" type="Vector3" setter="set_origin_offset" getter="get_origin_offset" default="Vector3( 0, 0, 0 )">
|
<member name="origin_offset" type="Vector3" setter="set_origin_offset" getter="get_origin_offset" default="Vector3( 0, 0, 0 )">
|
||||||
Sets the origin offset to be used when this [ReflectionProbe] is in [member box_projection] mode. This can be set to a non-zero value to ensure a reflection fits a rectangle-shaped room, while reducing the amount of objects that "get in the way" of the reflection.
|
Sets the origin offset to be used when this [ReflectionProbe] is in [member box_projection] mode. This can be set to a non-zero value to ensure a reflection fits a rectangle-shaped room, while reducing the amount of objects that "get in the way" of the reflection.
|
||||||
|
@ -115,7 +115,7 @@ void IP_Unix::_resolve_hostname(List<IP_Address> &r_addresses, const String &p_h
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IP_Address ip = _sockaddr2ip(next->ai_addr);
|
IP_Address ip = _sockaddr2ip(next->ai_addr);
|
||||||
if (!r_addresses.find(ip)) {
|
if (ip.is_valid() && !r_addresses.find(ip)) {
|
||||||
r_addresses.push_back(ip);
|
r_addresses.push_back(ip);
|
||||||
}
|
}
|
||||||
next = next->ai_next;
|
next = next->ai_next;
|
||||||
|
@ -77,7 +77,7 @@ void SkeletonEditor::create_physical_skeleton() {
|
|||||||
if (!bones_infos[parent].physical_bone) {
|
if (!bones_infos[parent].physical_bone) {
|
||||||
bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
|
bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
|
||||||
|
|
||||||
ur->create_action(TTR("Create physical bones"));
|
ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL);
|
||||||
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
|
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
|
||||||
ur->add_do_reference(bones_infos[parent].physical_bone);
|
ur->add_do_reference(bones_infos[parent].physical_bone);
|
||||||
ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone);
|
ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone);
|
||||||
|
@ -103,10 +103,10 @@ def find_msbuild_tools_path_reg():
|
|||||||
raise ValueError("Cannot find `installationPath` entry")
|
raise ValueError("Cannot find `installationPath` entry")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print("Error reading output from vswhere: " + e.message)
|
print("Error reading output from vswhere: " + e.message)
|
||||||
except WindowsError:
|
except subprocess.CalledProcessError as e:
|
||||||
pass # Fine, vswhere not found
|
print(e.output)
|
||||||
except (subprocess.CalledProcessError, OSError):
|
except OSError as e:
|
||||||
pass
|
print(e)
|
||||||
|
|
||||||
# Try to find 14.0 in the Registry
|
# Try to find 14.0 in the Registry
|
||||||
|
|
||||||
|
@ -225,33 +225,34 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
|
|||||||
*/
|
*/
|
||||||
Config.prototype.update = function (opts) {
|
Config.prototype.update = function (opts) {
|
||||||
const config = opts || {};
|
const config = opts || {};
|
||||||
function parse(key, def) {
|
const me = this;
|
||||||
|
function parse(key) {
|
||||||
if (typeof (config[key]) === 'undefined') {
|
if (typeof (config[key]) === 'undefined') {
|
||||||
return def;
|
return me[key];
|
||||||
}
|
}
|
||||||
return config[key];
|
return config[key];
|
||||||
}
|
}
|
||||||
// Module config
|
// Module config
|
||||||
this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit);
|
this.unloadAfterInit = parse('unloadAfterInit');
|
||||||
this.onPrintError = parse('onPrintError', this.onPrintError);
|
this.onPrintError = parse('onPrintError');
|
||||||
this.onPrint = parse('onPrint', this.onPrint);
|
this.onPrint = parse('onPrint');
|
||||||
this.onProgress = parse('onProgress', this.onProgress);
|
this.onProgress = parse('onProgress');
|
||||||
|
|
||||||
// Godot config
|
// Godot config
|
||||||
this.canvas = parse('canvas', this.canvas);
|
this.canvas = parse('canvas');
|
||||||
this.executable = parse('executable', this.executable);
|
this.executable = parse('executable');
|
||||||
this.mainPack = parse('mainPack', this.mainPack);
|
this.mainPack = parse('mainPack');
|
||||||
this.locale = parse('locale', this.locale);
|
this.locale = parse('locale');
|
||||||
this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
|
this.canvasResizePolicy = parse('canvasResizePolicy');
|
||||||
this.persistentPaths = parse('persistentPaths', this.persistentPaths);
|
this.persistentPaths = parse('persistentPaths');
|
||||||
this.persistentDrops = parse('persistentDrops', this.persistentDrops);
|
this.persistentDrops = parse('persistentDrops');
|
||||||
this.experimentalVK = parse('experimentalVK', this.experimentalVK);
|
this.experimentalVK = parse('experimentalVK');
|
||||||
this.focusCanvas = parse('focusCanvas', this.focusCanvas);
|
this.focusCanvas = parse('focusCanvas');
|
||||||
this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
|
this.gdnativeLibs = parse('gdnativeLibs');
|
||||||
this.fileSizes = parse('fileSizes', this.fileSizes);
|
this.fileSizes = parse('fileSizes');
|
||||||
this.args = parse('args', this.args);
|
this.args = parse('args');
|
||||||
this.onExecute = parse('onExecute', this.onExecute);
|
this.onExecute = parse('onExecute');
|
||||||
this.onExit = parse('onExit', this.onExit);
|
this.onExit = parse('onExit');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +87,7 @@ const GodotInputGamepads = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
init: function (onchange) {
|
init: function (onchange) {
|
||||||
GodotEventListeners.samples = [];
|
GodotInputGamepads.samples = [];
|
||||||
function add(pad) {
|
function add(pad) {
|
||||||
const guid = GodotInputGamepads.get_guid(pad);
|
const guid = GodotInputGamepads.get_guid(pad);
|
||||||
const c_id = GodotRuntime.allocString(pad.id);
|
const c_id = GodotRuntime.allocString(pad.id);
|
||||||
|
@ -140,6 +140,11 @@ __declspec(dllexport) int widechar_main(int argc, wchar_t **argv) {
|
|||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
|
#ifndef TOOLS_ENABLED
|
||||||
|
// Workaround to prevent LTCG (MSVC LTO) from removing "pck" section
|
||||||
|
char *dummy_guard = dummy;
|
||||||
|
#endif
|
||||||
|
|
||||||
char **argv_utf8 = new char *[argc];
|
char **argv_utf8 = new char *[argc];
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
@ -107,15 +107,23 @@ static String format_error_message(DWORD id) {
|
|||||||
|
|
||||||
extern HINSTANCE godot_hinstance;
|
extern HINSTANCE godot_hinstance;
|
||||||
|
|
||||||
|
void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) {
|
||||||
|
const HANDLE h_existing = GetStdHandle(p_std_handle);
|
||||||
|
if (h_existing != INVALID_HANDLE_VALUE) { // Redirect only if attached console have a valid handle.
|
||||||
|
const HANDLE h_cpp = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(p_cpp_stream)));
|
||||||
|
if (h_cpp == INVALID_HANDLE_VALUE) { // Redirect only if it's not already redirected to the pipe or file.
|
||||||
|
FILE *fp = p_cpp_stream;
|
||||||
|
freopen_s(&fp, p_file_name, p_mode, p_cpp_stream); // Redirect stream.
|
||||||
|
setvbuf(p_cpp_stream, nullptr, _IONBF, 0); // Disable stream buffering.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RedirectIOToConsole() {
|
void RedirectIOToConsole() {
|
||||||
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
FILE *fpstdin = stdin;
|
RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
|
||||||
FILE *fpstdout = stdout;
|
RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
|
||||||
FILE *fpstderr = stderr;
|
RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
|
||||||
|
|
||||||
freopen_s(&fpstdin, "CONIN$", "r", stdin);
|
|
||||||
freopen_s(&fpstdout, "CONOUT$", "w", stdout);
|
|
||||||
freopen_s(&fpstderr, "CONOUT$", "w", stderr);
|
|
||||||
|
|
||||||
printf("\n"); // Make sure our output is starting from the new line.
|
printf("\n"); // Make sure our output is starting from the new line.
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,8 @@ void TextureButton::_notification(int p_what) {
|
|||||||
bool draw_focus = (has_focus() && focused.is_valid());
|
bool draw_focus = (has_focus() && focused.is_valid());
|
||||||
|
|
||||||
// If no other texture is valid, try using focused texture.
|
// If no other texture is valid, try using focused texture.
|
||||||
if (!texdraw.is_valid() && draw_focus) {
|
bool draw_focus_only = draw_focus && !texdraw.is_valid();
|
||||||
|
if (draw_focus_only) {
|
||||||
texdraw = focused;
|
texdraw = focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +231,7 @@ void TextureButton::_notification(int p_what) {
|
|||||||
size.width *= hflip ? -1.0f : 1.0f;
|
size.width *= hflip ? -1.0f : 1.0f;
|
||||||
size.height *= vflip ? -1.0f : 1.0f;
|
size.height *= vflip ? -1.0f : 1.0f;
|
||||||
|
|
||||||
if (texdraw == focused) {
|
if (draw_focus_only) {
|
||||||
// Do nothing, we only needed to calculate the rectangle.
|
// Do nothing, we only needed to calculate the rectangle.
|
||||||
} else if (_tile) {
|
} else if (_tile) {
|
||||||
draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
|
draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
|
||||||
|
Loading…
Reference in New Issue
Block a user