diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/config.py | 4 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 6 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 8 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/AABB.cs | 200 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Color.cs | 5 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Plane.cs | 9 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Rect2.cs | 122 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Vector2.cs | 5 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Vector3.cs | 5 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 46 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 76 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.h | 3 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_log.cpp | 3 | ||||
-rw-r--r-- | modules/mono/utils/thread_local.cpp | 4 | ||||
-rw-r--r-- | modules/mono/utils/thread_local.h | 3 |
15 files changed, 285 insertions, 214 deletions
diff --git a/modules/mono/config.py b/modules/mono/config.py index c4f8dcfde8..70fd1a35f1 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -265,11 +265,13 @@ def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext): def pkgconfig_try_find_mono_version(): + from compat import decode_utf8 + lines = subprocess.check_output(['pkg-config', 'monosgen-2', '--modversion']).splitlines() greater_version = None for line in lines: try: - version = LooseVersion(line) + version = LooseVersion(decode_utf8(line)) if greater_version is None or version > greater_version: greater_version = version except ValueError: diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index cd1a8266ed..b8b77924f7 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2118,11 +2118,7 @@ Error CSharpScript::reload(bool p_keep_state) { if (script_class) { #ifdef DEBUG_ENABLED - if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print(String("Found class " + script_class->get_namespace() + "." + - script_class->get_name() + " for script " + get_path() + "\n") - .utf8()); - } + print_verbose("Found class " + script_class->get_namespace() + "." + script_class->get_name() + " for script " + get_path()); #endif tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute)); diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 0fb8734410..2faab1718d 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -97,8 +97,7 @@ MonoString *godot_icall_BuildInstance_get_MSBuildPath() { return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); } - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Trying with '" PROP_NAME_MSBUILD_MONO "'...\n"); + print_verbose("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Trying with '" PROP_NAME_MSBUILD_MONO "'..."); } // FALL THROUGH case GodotSharpBuilds::MSBUILD_MONO: { String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat"); @@ -556,8 +555,9 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { exited = true; exit_code = klass->get_field("exitCode")->get_int_value(mono_object); - if (exit_code != 0 && OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print(String("MSBuild finished with exit code " + itos(exit_code) + "\n").utf8()); + if (exit_code != 0) { + print_verbose("MSBuild finished with exit code " + itos(exit_code)); + } build_tab->on_build_exit(exit_code == 0 ? MonoBuildTab::RESULT_SUCCESS : MonoBuildTab::RESULT_ERROR); } else { diff --git a/modules/mono/glue/cs_files/AABB.cs b/modules/mono/glue/cs_files/AABB.cs index 39f2d2ed51..0df2e615f1 100644 --- a/modules/mono/glue/cs_files/AABB.cs +++ b/modules/mono/glue/cs_files/AABB.cs @@ -15,39 +15,33 @@ namespace Godot { public struct AABB : IEquatable<AABB> { - private Vector3 position; - private Vector3 size; + private Vector3 _position; + private Vector3 _size; public Vector3 Position { - get - { - return position; - } + get { return _position; } + set { _position = value; } } public Vector3 Size { - get - { - return size; - } + get { return _size; } + set { _size = value; } } public Vector3 End { - get - { - return position + size; - } + get { return _position + _size; } + set { _size = value - _position; } } public bool Encloses(AABB with) { - Vector3 src_min = position; - Vector3 src_max = position + size; - Vector3 dst_min = with.position; - Vector3 dst_max = with.position + with.size; + Vector3 src_min = _position; + Vector3 src_max = _position + _size; + Vector3 dst_min = with._position; + Vector3 dst_max = with._position + with._size; return src_min.x <= dst_min.x && src_max.x > dst_max.x && @@ -59,8 +53,8 @@ namespace Godot public AABB Expand(Vector3 to_point) { - Vector3 begin = position; - Vector3 end = position + size; + Vector3 begin = _position; + Vector3 end = _position + _size; if (to_point.x < begin.x) begin.x = to_point.x; @@ -81,7 +75,7 @@ namespace Godot public real_t GetArea() { - return size.x * size.y * size.z; + return _size.x * _size.y * _size.z; } public Vector3 GetEndpoint(int idx) @@ -89,21 +83,21 @@ namespace Godot switch (idx) { case 0: - return new Vector3(position.x, position.y, position.z); + return new Vector3(_position.x, _position.y, _position.z); case 1: - return new Vector3(position.x, position.y, position.z + size.z); + return new Vector3(_position.x, _position.y, _position.z + _size.z); case 2: - return new Vector3(position.x, position.y + size.y, position.z); + return new Vector3(_position.x, _position.y + _size.y, _position.z); case 3: - return new Vector3(position.x, position.y + size.y, position.z + size.z); + return new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z); case 4: - return new Vector3(position.x + size.x, position.y, position.z); + return new Vector3(_position.x + _size.x, _position.y, _position.z); case 5: - return new Vector3(position.x + size.x, position.y, position.z + size.z); + return new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z); case 6: - return new Vector3(position.x + size.x, position.y + size.y, position.z); + return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z); case 7: - return new Vector3(position.x + size.x, position.y + size.y, position.z + size.z); + return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z); default: throw new ArgumentOutOfRangeException(nameof(idx), String.Format("Index is {0}, but a value from 0 to 7 is expected.", idx)); } @@ -112,15 +106,15 @@ namespace Godot public Vector3 GetLongestAxis() { var axis = new Vector3(1f, 0f, 0f); - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y > max_size) + if (_size.y > max_size) { axis = new Vector3(0f, 1f, 0f); - max_size = size.y; + max_size = _size.y; } - if (size.z > max_size) + if (_size.z > max_size) { axis = new Vector3(0f, 0f, 1f); } @@ -131,15 +125,15 @@ namespace Godot public Vector3.Axis GetLongestAxisIndex() { var axis = Vector3.Axis.X; - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y > max_size) + if (_size.y > max_size) { axis = Vector3.Axis.Y; - max_size = size.y; + max_size = _size.y; } - if (size.z > max_size) + if (_size.z > max_size) { axis = Vector3.Axis.Z; } @@ -149,13 +143,13 @@ namespace Godot public real_t GetLongestAxisSize() { - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y > max_size) - max_size = size.y; + if (_size.y > max_size) + max_size = _size.y; - if (size.z > max_size) - max_size = size.z; + if (_size.z > max_size) + max_size = _size.z; return max_size; } @@ -163,15 +157,15 @@ namespace Godot public Vector3 GetShortestAxis() { var axis = new Vector3(1f, 0f, 0f); - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y < max_size) + if (_size.y < max_size) { axis = new Vector3(0f, 1f, 0f); - max_size = size.y; + max_size = _size.y; } - if (size.z < max_size) + if (_size.z < max_size) { axis = new Vector3(0f, 0f, 1f); } @@ -182,15 +176,15 @@ namespace Godot public Vector3.Axis GetShortestAxisIndex() { var axis = Vector3.Axis.X; - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y < max_size) + if (_size.y < max_size) { axis = Vector3.Axis.Y; - max_size = size.y; + max_size = _size.y; } - if (size.z < max_size) + if (_size.z < max_size) { axis = Vector3.Axis.Z; } @@ -200,21 +194,21 @@ namespace Godot public real_t GetShortestAxisSize() { - real_t max_size = size.x; + real_t max_size = _size.x; - if (size.y < max_size) - max_size = size.y; + if (_size.y < max_size) + max_size = _size.y; - if (size.z < max_size) - max_size = size.z; + if (_size.z < max_size) + max_size = _size.z; return max_size; } public Vector3 GetSupport(Vector3 dir) { - Vector3 half_extents = size * 0.5f; - Vector3 ofs = position + half_extents; + Vector3 half_extents = _size * 0.5f; + Vector3 ofs = _position + half_extents; return ofs + new Vector3( dir.x > 0f ? -half_extents.x : half_extents.x, @@ -226,39 +220,39 @@ namespace Godot { var res = this; - res.position.x -= by; - res.position.y -= by; - res.position.z -= by; - res.size.x += 2.0f * by; - res.size.y += 2.0f * by; - res.size.z += 2.0f * by; + res._position.x -= by; + res._position.y -= by; + res._position.z -= by; + res._size.x += 2.0f * by; + res._size.y += 2.0f * by; + res._size.z += 2.0f * by; return res; } public bool HasNoArea() { - return size.x <= 0f || size.y <= 0f || size.z <= 0f; + return _size.x <= 0f || _size.y <= 0f || _size.z <= 0f; } public bool HasNoSurface() { - return size.x <= 0f && size.y <= 0f && size.z <= 0f; + return _size.x <= 0f && _size.y <= 0f && _size.z <= 0f; } public bool HasPoint(Vector3 point) { - if (point.x < position.x) + if (point.x < _position.x) return false; - if (point.y < position.y) + if (point.y < _position.y) return false; - if (point.z < position.z) + if (point.z < _position.z) return false; - if (point.x > position.x + size.x) + if (point.x > _position.x + _size.x) return false; - if (point.y > position.y + size.y) + if (point.y > _position.y + _size.y) return false; - if (point.z > position.z + size.z) + if (point.z > _position.z + _size.z) return false; return true; @@ -266,10 +260,10 @@ namespace Godot public AABB Intersection(AABB with) { - Vector3 src_min = position; - Vector3 src_max = position + size; - Vector3 dst_min = with.position; - Vector3 dst_max = with.position + with.size; + Vector3 src_min = _position; + Vector3 src_max = _position + _size; + Vector3 dst_min = with._position; + Vector3 dst_max = with._position + with._size; Vector3 min, max; @@ -302,17 +296,17 @@ namespace Godot public bool Intersects(AABB with) { - if (position.x >= with.position.x + with.size.x) + if (_position.x >= with._position.x + with._size.x) return false; - if (position.x + size.x <= with.position.x) + if (_position.x + _size.x <= with._position.x) return false; - if (position.y >= with.position.y + with.size.y) + if (_position.y >= with._position.y + with._size.y) return false; - if (position.y + size.y <= with.position.y) + if (_position.y + _size.y <= with._position.y) return false; - if (position.z >= with.position.z + with.size.z) + if (_position.z >= with._position.z + with._size.z) return false; - if (position.z + size.z <= with.position.z) + if (_position.z + _size.z <= with._position.z) return false; return true; @@ -322,14 +316,14 @@ namespace Godot { Vector3[] points = { - new Vector3(position.x, position.y, position.z), - new Vector3(position.x, position.y, position.z + size.z), - new Vector3(position.x, position.y + size.y, position.z), - new Vector3(position.x, position.y + size.y, position.z + size.z), - new Vector3(position.x + size.x, position.y, position.z), - new Vector3(position.x + size.x, position.y, position.z + size.z), - new Vector3(position.x + size.x, position.y + size.y, position.z), - new Vector3(position.x + size.x, position.y + size.y, position.z + size.z) + new Vector3(_position.x, _position.y, _position.z), + new Vector3(_position.x, _position.y, _position.z + _size.z), + new Vector3(_position.x, _position.y + _size.y, _position.z), + new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z), + new Vector3(_position.x + _size.x, _position.y, _position.z), + new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z), + new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z), + new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z) }; bool over = false; @@ -355,8 +349,8 @@ namespace Godot { real_t seg_from = from[i]; real_t seg_to = to[i]; - real_t box_begin = position[i]; - real_t box_end = box_begin + size[i]; + real_t box_begin = _position[i]; + real_t box_end = box_begin + _size[i]; real_t cmin, cmax; if (seg_from < seg_to) @@ -394,10 +388,10 @@ namespace Godot public AABB Merge(AABB with) { - Vector3 beg_1 = position; - Vector3 beg_2 = with.position; - var end_1 = new Vector3(size.x, size.y, size.z) + beg_1; - var end_2 = new Vector3(with.size.x, with.size.y, with.size.z) + beg_2; + Vector3 beg_1 = _position; + Vector3 beg_2 = with._position; + var end_1 = new Vector3(_size.x, _size.y, _size.z) + beg_1; + var end_2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg_2; var min = new Vector3( beg_1.x < beg_2.x ? beg_1.x : beg_2.x, @@ -417,8 +411,8 @@ namespace Godot // Constructors public AABB(Vector3 position, Vector3 size) { - this.position = position; - this.size = size; + _position = position; + _size = size; } public static bool operator ==(AABB left, AABB right) @@ -443,20 +437,20 @@ namespace Godot public bool Equals(AABB other) { - return position == other.position && size == other.size; + return _position == other._position && _size == other._size; } public override int GetHashCode() { - return position.GetHashCode() ^ size.GetHashCode(); + return _position.GetHashCode() ^ _size.GetHashCode(); } public override string ToString() { return String.Format("{0} - {1}", new object[] { - position.ToString(), - size.ToString() + _position.ToString(), + _size.ToString() }); } @@ -464,8 +458,8 @@ namespace Godot { return String.Format("{0} - {1}", new object[] { - position.ToString(format), - size.ToString(format) + _position.ToString(format), + _size.ToString(format) }); } } diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs index 1195071bd3..49e04b333a 100644 --- a/modules/mono/glue/cs_files/Color.cs +++ b/modules/mono/glue/cs_files/Color.cs @@ -258,11 +258,6 @@ namespace Godot return res; } - public float Gray() - { - return (r + g + b) / 3.0f; - } - public Color Inverted() { return new Color( diff --git a/modules/mono/glue/cs_files/Plane.cs b/modules/mono/glue/cs_files/Plane.cs index 1020f06bf5..9611dce11e 100644 --- a/modules/mono/glue/cs_files/Plane.cs +++ b/modules/mono/glue/cs_files/Plane.cs @@ -145,6 +145,15 @@ namespace Godot return point - _normal * DistanceTo(point); } + // Constants + private static readonly Plane _planeYZ = new Plane(1, 0, 0, 0); + private static readonly Plane _planeXZ = new Plane(0, 1, 0, 0); + private static readonly Plane _planeXY = new Plane(0, 0, 1, 0); + + public static Plane PlaneYZ { get { return _planeYZ; } } + public static Plane PlaneXZ { get { return _planeXZ; } } + public static Plane PlaneXY { get { return _planeXY; } } + // Constructors public Plane(real_t a, real_t b, real_t c, real_t d) { diff --git a/modules/mono/glue/cs_files/Rect2.cs b/modules/mono/glue/cs_files/Rect2.cs index 6f16656573..cb25c267bc 100644 --- a/modules/mono/glue/cs_files/Rect2.cs +++ b/modules/mono/glue/cs_files/Rect2.cs @@ -11,24 +11,25 @@ namespace Godot [StructLayout(LayoutKind.Sequential)] public struct Rect2 : IEquatable<Rect2> { - private Vector2 position; - private Vector2 size; + private Vector2 _position; + private Vector2 _size; public Vector2 Position { - get { return position; } - set { position = value; } + get { return _position; } + set { _position = value; } } public Vector2 Size { - get { return size; } - set { size = value; } + get { return _size; } + set { _size = value; } } public Vector2 End { - get { return position + size; } + get { return _position + _size; } + set { _size = value - _position; } } public real_t Area @@ -36,6 +37,13 @@ namespace Godot get { return GetArea(); } } + public Rect2 Abs() + { + Vector2 end = End; + Vector2 topLeft = new Vector2(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); + return new Rect2(topLeft, _size.Abs()); + } + public Rect2 Clip(Rect2 b) { var newRect = b; @@ -43,31 +51,31 @@ namespace Godot if (!Intersects(newRect)) return new Rect2(); - newRect.position.x = Mathf.Max(b.position.x, position.x); - newRect.position.y = Mathf.Max(b.position.y, position.y); + newRect._position.x = Mathf.Max(b._position.x, _position.x); + newRect._position.y = Mathf.Max(b._position.y, _position.y); - Vector2 bEnd = b.position + b.size; - Vector2 end = position + size; + Vector2 bEnd = b._position + b._size; + Vector2 end = _position + _size; - newRect.size.x = Mathf.Min(bEnd.x, end.x) - newRect.position.x; - newRect.size.y = Mathf.Min(bEnd.y, end.y) - newRect.position.y; + newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; + newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; return newRect; } public bool Encloses(Rect2 b) { - return b.position.x >= position.x && b.position.y >= position.y && - b.position.x + b.size.x < position.x + size.x && - b.position.y + b.size.y < position.y + size.y; + return b._position.x >= _position.x && b._position.y >= _position.y && + b._position.x + b._size.x < _position.x + _size.x && + b._position.y + b._size.y < _position.y + _size.y; } public Rect2 Expand(Vector2 to) { var expanded = this; - Vector2 begin = expanded.position; - Vector2 end = expanded.position + expanded.size; + Vector2 begin = expanded._position; + Vector2 end = expanded._position + expanded._size; if (to.x < begin.x) begin.x = to.x; @@ -79,25 +87,25 @@ namespace Godot if (to.y > end.y) end.y = to.y; - expanded.position = begin; - expanded.size = end - begin; + expanded._position = begin; + expanded._size = end - begin; return expanded; } public real_t GetArea() { - return size.x * size.y; + return _size.x * _size.y; } public Rect2 Grow(real_t by) { var g = this; - g.position.x -= by; - g.position.y -= by; - g.size.x += by * 2; - g.size.y += by * 2; + g._position.x -= by; + g._position.y -= by; + g._size.x += by * 2; + g._size.y += by * 2; return g; } @@ -106,10 +114,10 @@ namespace Godot { var g = this; - g.position.x -= left; - g.position.y -= top; - g.size.x += left + right; - g.size.y += top + bottom; + g._position.x -= left; + g._position.y -= top; + g._size.x += left + right; + g._size.y += top + bottom; return g; } @@ -128,19 +136,19 @@ namespace Godot public bool HasNoArea() { - return size.x <= 0 || size.y <= 0; + return _size.x <= 0 || _size.y <= 0; } public bool HasPoint(Vector2 point) { - if (point.x < position.x) + if (point.x < _position.x) return false; - if (point.y < position.y) + if (point.y < _position.y) return false; - if (point.x >= position.x + size.x) + if (point.x >= _position.x + _size.x) return false; - if (point.y >= position.y + size.y) + if (point.y >= _position.y + _size.y) return false; return true; @@ -148,13 +156,13 @@ namespace Godot public bool Intersects(Rect2 b) { - if (position.x > b.position.x + b.size.x) + if (_position.x > b._position.x + b._size.x) return false; - if (position.x + size.x < b.position.x) + if (_position.x + _size.x < b._position.x) return false; - if (position.y > b.position.y + b.size.y) + if (_position.y > b._position.y + b._size.y) return false; - if (position.y + size.y < b.position.y) + if (_position.y + _size.y < b._position.y) return false; return true; @@ -164,13 +172,13 @@ namespace Godot { Rect2 newRect; - newRect.position.x = Mathf.Min(b.position.x, position.x); - newRect.position.y = Mathf.Min(b.position.y, position.y); + newRect._position.x = Mathf.Min(b._position.x, _position.x); + newRect._position.y = Mathf.Min(b._position.y, _position.y); - newRect.size.x = Mathf.Max(b.position.x + b.size.x, position.x + size.x); - newRect.size.y = Mathf.Max(b.position.y + b.size.y, position.y + size.y); + newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); + newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); - newRect.size = newRect.size - newRect.position; // Make relative again + newRect._size = newRect._size - newRect._position; // Make relative again return newRect; } @@ -178,23 +186,23 @@ namespace Godot // Constructors public Rect2(Vector2 position, Vector2 size) { - this.position = position; - this.size = size; + _position = position; + _size = size; } public Rect2(Vector2 position, real_t width, real_t height) { - this.position = position; - size = new Vector2(width, height); + _position = position; + _size = new Vector2(width, height); } public Rect2(real_t x, real_t y, Vector2 size) { - position = new Vector2(x, y); - this.size = size; + _position = new Vector2(x, y); + _size = size; } public Rect2(real_t x, real_t y, real_t width, real_t height) { - position = new Vector2(x, y); - size = new Vector2(width, height); + _position = new Vector2(x, y); + _size = new Vector2(width, height); } public static bool operator ==(Rect2 left, Rect2 right) @@ -219,20 +227,20 @@ namespace Godot public bool Equals(Rect2 other) { - return position.Equals(other.position) && size.Equals(other.size); + return _position.Equals(other._position) && _size.Equals(other._size); } public override int GetHashCode() { - return position.GetHashCode() ^ size.GetHashCode(); + return _position.GetHashCode() ^ _size.GetHashCode(); } public override string ToString() { return String.Format("({0}, {1})", new object[] { - position.ToString(), - size.ToString() + _position.ToString(), + _size.ToString() }); } @@ -240,8 +248,8 @@ namespace Godot { return String.Format("({0}, {1})", new object[] { - position.ToString(format), - size.ToString(format) + _position.ToString(format), + _size.ToString(format) }); } } diff --git a/modules/mono/glue/cs_files/Vector2.cs b/modules/mono/glue/cs_files/Vector2.cs index 14c8de6986..080b8802ba 100644 --- a/modules/mono/glue/cs_files/Vector2.cs +++ b/modules/mono/glue/cs_files/Vector2.cs @@ -184,6 +184,11 @@ namespace Godot return result; } + public Vector2 Project(Vector2 onNormal) + { + return onNormal * (Dot(onNormal) / onNormal.LengthSquared()); + } + public Vector2 Reflect(Vector2 n) { return 2.0f * n * Dot(n) - this; diff --git a/modules/mono/glue/cs_files/Vector3.cs b/modules/mono/glue/cs_files/Vector3.cs index 861d9c54d9..6fffe5e4d6 100644 --- a/modules/mono/glue/cs_files/Vector3.cs +++ b/modules/mono/glue/cs_files/Vector3.cs @@ -210,6 +210,11 @@ namespace Godot ); } + public Vector3 Project(Vector3 onNormal) + { + return onNormal * (Dot(onNormal) / onNormal.LengthSquared()); + } + public Vector3 Reflect(Vector3 n) { #if DEBUG diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index f564b93f8f..fadac941e9 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -148,7 +148,7 @@ void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); - OS::get_singleton()->print("Mono: Initializing module...\n"); + print_verbose("Mono: Initializing module..."); #ifdef DEBUG_METHODS_ENABLED _initialize_and_check_api_hashes(); @@ -202,7 +202,7 @@ void GDMono::initialize() { runtime_initialized = true; - OS::get_singleton()->print("Mono: Runtime initialized\n"); + print_verbose("Mono: Runtime initialized"); // mscorlib assembly MUST be present at initialization ERR_EXPLAIN("Mono: Failed to load mscorlib assembly"); @@ -226,7 +226,7 @@ void GDMono::initialize() { #ifdef DEBUG_ENABLED bool debugger_attached = _wait_for_debugger_msecs(500); if (!debugger_attached && OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Debugger wait timeout\n"); + print_error("Mono: Debugger wait timeout"); #endif _register_internal_calls(); @@ -256,7 +256,7 @@ void GDMono::initialize() { metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); } - OS::get_singleton()->print("Mono: Proceeding to unload scripts domain because of invalid API assemblies\n"); + print_line("Mono: Proceeding to unload scripts domain because of invalid API assemblies."); Error err = _unload_scripts_domain(); if (err != OK) { @@ -269,11 +269,10 @@ void GDMono::initialize() { } } #else - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print("Mono: Glue disabled, ignoring script assemblies\n"); + print_verbose("Mono: Glue disabled, ignoring script assemblies."); #endif - OS::get_singleton()->print("Mono: INITIALIZED\n"); + print_verbose("Mono: INITIALIZED"); } #ifndef MONO_GLUE_DISABLED @@ -352,8 +351,7 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo CRASH_COND(!r_assembly); - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print((String() + "Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...\n").utf8()); + print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "..."); MonoImageOpenStatus status = MONO_IMAGE_OK; MonoAssembly *assembly = mono_assembly_load_full(p_aname, NULL, &status, p_refonly); @@ -372,8 +370,7 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo *r_assembly = *stored_assembly; - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print(String("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path() + "\n").utf8()); + print_verbose("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path()); return true; } @@ -500,7 +497,7 @@ bool GDMono::_load_project_assembly() { mono_assembly_set_main(project_assembly->get_assembly()); } else { if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Failed to load project assembly\n"); + print_error("Mono: Failed to load project assembly"); } return success; @@ -510,13 +507,13 @@ bool GDMono::_load_api_assemblies() { if (!_load_core_api_assembly()) { if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Failed to load Core API assembly\n"); + print_error("Mono: Failed to load Core API assembly"); return false; } else { #ifdef TOOLS_ENABLED if (!_load_editor_api_assembly()) { if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Failed to load Editor API assembly\n"); + print_error("Mono: Failed to load Editor API assembly"); return false; } #endif @@ -593,9 +590,7 @@ Error GDMono::_load_scripts_domain() { ERR_FAIL_COND_V(scripts_domain != NULL, ERR_BUG); - if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print("Mono: Loading scripts domain...\n"); - } + print_verbose("Mono: Loading scripts domain..."); scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain"); @@ -611,9 +606,7 @@ Error GDMono::_unload_scripts_domain() { ERR_FAIL_NULL_V(scripts_domain, ERR_BUG); - if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print("Mono: Unloading scripts domain...\n"); - } + print_verbose("Mono: Unloading scripts domain..."); _GodotSharp::get_singleton()->_dispose_callback(); @@ -661,9 +654,7 @@ Error GDMono::_load_tools_domain() { ERR_FAIL_COND_V(tools_domain != NULL, ERR_BUG); - if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print("Mono: Loading tools domain...\n"); - } + print_verbose("Mono: Loading tools domain..."); tools_domain = GDMonoUtils::create_domain("GodotEngine.ToolsDomain"); @@ -728,8 +719,7 @@ Error GDMono::reload_scripts_domain() { if (!_load_project_assembly()) return ERR_CANT_OPEN; #else - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print("Mono: Glue disabled, ignoring script assemblies\n"); + print_verbose("Mono: Glue disabled, ignoring script assemblies."); #endif return OK; @@ -742,9 +732,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { String domain_name = mono_domain_get_friendly_name(p_domain); - if (OS::get_singleton()->is_stdout_verbose()) { - OS::get_singleton()->print(String("Mono: Unloading domain `" + domain_name + "`...\n").utf8()); - } + print_verbose("Mono: Unloading domain `" + domain_name + "`..."); if (mono_domain_get() != root_domain) mono_domain_set(root_domain, true); @@ -877,7 +865,7 @@ GDMono::~GDMono() { GDMonoUtils::clear_cache(); - OS::get_singleton()->print("Mono: Runtime cleanup...\n"); + print_verbose("Mono: Runtime cleanup..."); runtime_initialized = false; mono_jit_cleanup(root_domain); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 9d3bee2176..27ce39b6d7 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -42,8 +42,25 @@ #include "gd_mono_class.h" bool GDMonoAssembly::no_search = false; +bool GDMonoAssembly::in_preload = false; + Vector<String> GDMonoAssembly::search_dirs; +void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, void *user_data) { + + if (no_search) + return; + + // If our search and preload hooks fail to load the assembly themselves, the mono runtime still might. + // Just do Assembly.LoadFrom("/Full/Path/On/Disk.dll"); + // In this case, we wouldn't have the assembly known in GDMono, which causes crashes + // if any class inside the assembly is looked up by Godot. + // And causing a lookup like that is as easy as throwing an exception defined in it... + // No, we can't make the assembly load hooks smart enough because they get passed a MonoAssemblyName* only, + // not the disk path passed to say Assembly.LoadFrom(). + _wrap_mono_assembly(assembly); +} + MonoAssembly *GDMonoAssembly::assembly_search_hook(MonoAssemblyName *aname, void *user_data) { return GDMonoAssembly::_search_hook(aname, user_data, false); } @@ -111,6 +128,8 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d return res ? res->get_assembly() : NULL; } +static _THREAD_LOCAL_(MonoImage *) image_corlib_loading = NULL; + MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly) { (void)user_data; // UNUSED @@ -138,16 +157,38 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse } } + { + // If we find the assembly here, we load it with `mono_assembly_load_from_full`, + // which in turn invokes load hooks before returning the MonoAssembly to us. + // One of the load hooks is `load_aot_module`. This hook can end up calling preload hooks + // again for the same assembly in certain in certain circumstances (the `do_load_image` part). + // If this is the case and we return NULL due to the no_search condition below, + // it will result in an internal crash later on. Therefore we need to return the assembly we didn't + // get yet from `mono_assembly_load_from_full`. Luckily we have the image, which already got it. + // This must be done here. If done in search hooks, it would cause `mono_assembly_load_from_full` + // to think another MonoAssembly for this assembly was already loaded, making it delete its own, + // when in fact both pointers were the same... This hooks thing is confusing. + if (image_corlib_loading) { + return mono_image_get_assembly(image_corlib_loading); + } + } + + if (no_search) + return NULL; + + no_search = true; + in_preload = true; + String name = mono_assembly_name_get_name(aname); bool has_extension = name.ends_with(".dll"); + GDMonoAssembly *res = NULL; if (has_extension ? name == "mscorlib.dll" : name == "mscorlib") { GDMonoAssembly **stored_assembly = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); if (stored_assembly) return (*stored_assembly)->get_assembly(); String path; - GDMonoAssembly *res = NULL; for (int i = 0; i < search_dirs.size(); i++) { const String &search_dir = search_dirs[i]; @@ -168,11 +209,12 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse } } } - - return res ? res->get_assembly() : NULL; } - return NULL; + no_search = false; + in_preload = false; + + return res ? res->get_assembly() : NULL; } GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) { @@ -192,12 +234,30 @@ GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const return assembly; } +void GDMonoAssembly::_wrap_mono_assembly(MonoAssembly *assembly) { + String name = mono_assembly_name_get_name(mono_assembly_get_name(assembly)); + + MonoImage *image = mono_assembly_get_image(assembly); + + GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, mono_image_get_filename(image))); + Error err = gdassembly->wrapper_for_image(image); + + if (err != OK) { + memdelete(gdassembly); + ERR_FAIL(); + } + + MonoDomain *domain = mono_domain_get(); + GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, gdassembly); +} + void GDMonoAssembly::initialize() { mono_install_assembly_search_hook(&assembly_search_hook, NULL); mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, NULL); mono_install_assembly_preload_hook(&assembly_preload_hook, NULL); mono_install_assembly_refonly_preload_hook(&assembly_refonly_preload_hook, NULL); + mono_install_assembly_load_hook(&assembly_load_hook, NULL); } Error GDMonoAssembly::load(bool p_refonly) { @@ -241,8 +301,16 @@ no_pdb: #endif + bool is_corlib_preload = in_preload && name == "mscorlib"; + + if (is_corlib_preload) + image_corlib_loading = image; + assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, refonly); + if (is_corlib_preload) + image_corlib_loading = NULL; + ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN); loaded = true; diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 5cf744a5a2..2c6d367fc6 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -89,8 +89,10 @@ class GDMonoAssembly { #endif static bool no_search; + static bool in_preload; static Vector<String> search_dirs; + static void assembly_load_hook(MonoAssembly *assembly, void *user_data); static MonoAssembly *assembly_search_hook(MonoAssemblyName *aname, void *user_data); static MonoAssembly *assembly_refonly_search_hook(MonoAssemblyName *aname, void *user_data); static MonoAssembly *assembly_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); @@ -100,6 +102,7 @@ class GDMonoAssembly { static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly); static GDMonoAssembly *_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly); + static void _wrap_mono_assembly(MonoAssembly *assembly); friend class GDMono; static void initialize(); diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index eabea8dc3c..5224d309de 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -152,8 +152,7 @@ void GDMonoLog::initialize() { log_level_id = log_level_get_id(log_level); if (log_file) { - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print(String("Mono: Logfile is " + log_file_path + "\n").utf8()); + print_verbose("Mono: Logfile is " + log_file_path); mono_trace_set_log_handler(gdmono_MonoLogCallback, this); } else { OS::get_singleton()->printerr("Mono: No log file, using default log handler\n"); diff --git a/modules/mono/utils/thread_local.cpp b/modules/mono/utils/thread_local.cpp index ae9f130518..a0e28fca5f 100644 --- a/modules/mono/utils/thread_local.cpp +++ b/modules/mono/utils/thread_local.cpp @@ -69,7 +69,7 @@ struct ThreadLocalStorage::Impl { #define _CALLBACK_FUNC_ #endif - Impl(void (_CALLBACK_FUNC_ *p_destr_callback_func)(void *)) { + Impl(void(_CALLBACK_FUNC_ *p_destr_callback_func)(void *)) { #ifdef WINDOWS_ENABLED dwFlsIndex = FlsAlloc(p_destr_callback_func); ERR_FAIL_COND(dwFlsIndex == FLS_OUT_OF_INDEXES); @@ -95,7 +95,7 @@ void ThreadLocalStorage::set_value(void *p_value) const { pimpl->set_value(p_value); } -void ThreadLocalStorage::alloc(void (_CALLBACK_FUNC_ *p_destr_callback)(void *)) { +void ThreadLocalStorage::alloc(void(_CALLBACK_FUNC_ *p_destr_callback)(void *)) { pimpl = memnew(ThreadLocalStorage::Impl(p_destr_callback)); } diff --git a/modules/mono/utils/thread_local.h b/modules/mono/utils/thread_local.h index 783e40dc01..84dae1d86b 100644 --- a/modules/mono/utils/thread_local.h +++ b/modules/mono/utils/thread_local.h @@ -76,7 +76,7 @@ struct ThreadLocalStorage { void *get_value() const; void set_value(void *p_value) const; - void alloc(void (_CALLBACK_FUNC_ *p_dest_callback)(void *)); + void alloc(void(_CALLBACK_FUNC_ *p_dest_callback)(void *)); void free(); private: @@ -95,7 +95,6 @@ class ThreadLocal { memdelete(static_cast<T *>(tls_data)); } - T *_tls_get_value() const { void *tls_data = storage.get_value(); |