diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gltf/extensions/gltf_light.cpp | 1 | ||||
-rw-r--r-- | modules/gltf/structures/gltf_camera.cpp | 1 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 44 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 3 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs | 3 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs | 57 |
6 files changed, 100 insertions, 9 deletions
diff --git a/modules/gltf/extensions/gltf_light.cpp b/modules/gltf/extensions/gltf_light.cpp index ab5a15c671..6923c765cb 100644 --- a/modules/gltf/extensions/gltf_light.cpp +++ b/modules/gltf/extensions/gltf_light.cpp @@ -109,6 +109,7 @@ void GLTFLight::set_outer_cone_angle(float p_outer_cone_angle) { Ref<GLTFLight> GLTFLight::from_node(const Light3D *p_light) { Ref<GLTFLight> l; l.instantiate(); + ERR_FAIL_COND_V_MSG(!p_light, l, "Tried to create a GLTFLight from a Light3D node, but the given node was null."); l->color = p_light->get_color(); if (cast_to<DirectionalLight3D>(p_light)) { l->light_type = "directional"; diff --git a/modules/gltf/structures/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp index 5069f39c4b..212b9b80c8 100644 --- a/modules/gltf/structures/gltf_camera.cpp +++ b/modules/gltf/structures/gltf_camera.cpp @@ -58,6 +58,7 @@ void GLTFCamera::_bind_methods() { Ref<GLTFCamera> GLTFCamera::from_node(const Camera3D *p_camera) { Ref<GLTFCamera> c; c.instantiate(); + ERR_FAIL_COND_V_MSG(!p_camera, c, "Tried to create a GLTFCamera from a Camera3D node, but the given node was null."); c->set_perspective(p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE); // GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees. c->set_fov(Math::deg_to_rad(p_camera->get_fov())); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 64792a795f..990a95821e 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -784,6 +784,13 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { for (Object *obj : script->instances) { script->pending_reload_instances.insert(obj->get_instance_id()); + // Since this script instance wasn't a placeholder, add it to the list of placeholders + // that will have to be eventually replaced with a script instance in case it turns into one. + // This list is not cleared after the reload and the collected instances only leave + // the list if the script is instantiated or if it was a tool script but becomes a + // non-tool script in a rebuild. + script->pending_replace_placeholders.insert(obj->get_instance_id()); + RefCounted *rc = Object::cast_to<RefCounted>(obj); if (rc) { rc_instances.push_back(Ref<RefCounted>(rc)); @@ -836,6 +843,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { obj->set_script(Ref<RefCounted>()); // Remove script and existing script instances (placeholder are not removed before domain reload) } + script->was_tool_before_reload = script->tool; script->_clear(); } @@ -924,24 +932,34 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { ScriptInstance *si = obj->get_script_instance(); + // Check if the script must be instantiated or kept as a placeholder + // when the script may not be a tool (see #65266) + bool replace_placeholder = script->pending_replace_placeholders.has(obj->get_instance_id()); + if (!script->is_tool() && script->was_tool_before_reload) { + // The script was a tool before the rebuild so the removal was intentional. + replace_placeholder = false; + script->pending_replace_placeholders.erase(obj->get_instance_id()); + } + #ifdef TOOLS_ENABLED if (si) { // If the script instance is not null, then it must be a placeholder. // Non-placeholder script instances are removed in godot_icall_Object_Disposed. CRASH_COND(!si->is_placeholder()); - if (script->is_tool() || ScriptServer::is_scripting_enabled()) { - // Replace placeholder with a script instance + if (replace_placeholder || script->is_tool() || ScriptServer::is_scripting_enabled()) { + // Replace placeholder with a script instance. CSharpScript::StateBackup &state_backup = script->pending_reload_state[obj_id]; - // Backup placeholder script instance state before replacing it with a script instance + // Backup placeholder script instance state before replacing it with a script instance. si->get_property_state(state_backup.properties); ScriptInstance *script_instance = script->instance_create(obj); if (script_instance) { script->placeholders.erase(static_cast<PlaceHolderScriptInstance *>(si)); + script->pending_replace_placeholders.erase(obj->get_instance_id()); obj->set_script_instance(script_instance); } } @@ -951,8 +969,24 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { #else CRASH_COND(si != nullptr); #endif - // Re-create script instance - obj->set_script(script); // will create the script instance as well + + // Re-create the script instance. + if (replace_placeholder || script->is_tool() || ScriptServer::is_scripting_enabled()) { + // Create script instance or replace placeholder with a script instance. + ScriptInstance *script_instance = script->instance_create(obj); + + if (script_instance) { + script->pending_replace_placeholders.erase(obj->get_instance_id()); + obj->set_script_instance(script_instance); + continue; + } + } + // The script instance could not be instantiated or wasn't in the list of placeholders to replace. + obj->set_script(script); +#if DEBUG_ENABLED + // If we reached here, the instantiated script must be a placeholder. + CRASH_COND(!obj->get_script_instance()->is_placeholder()); +#endif } } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 3509a5c87d..f2844a051d 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -90,6 +90,9 @@ class CSharpScript : public Script { HashSet<ObjectID> pending_reload_instances; RBMap<ObjectID, StateBackup> pending_reload_state; + + bool was_tool_before_reload = false; + HashSet<ObjectID> pending_replace_placeholders; #endif String source; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index 3884781988..092724a6b1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -130,7 +130,6 @@ namespace Godot.Bridge { // Performance is not critical here as this will be replaced with source generators. Type scriptType = _scriptTypeBiMap.GetScriptType(scriptPtr); - var obj = (Object)FormatterServices.GetUninitializedObject(scriptType); var ctor = scriptType .GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) @@ -151,6 +150,8 @@ namespace Godot.Bridge } } + var obj = (Object)FormatterServices.GetUninitializedObject(scriptType); + var parameters = ctor.GetParameters(); int paramCount = parameters.Length; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs index d1962c68cf..e2da41ff47 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -187,7 +187,7 @@ namespace Godot ( Mathf.CubicInterpolate(x, b.x, preA.x, postB.x, weight), Mathf.CubicInterpolate(y, b.y, preA.y, postB.y, weight), - Mathf.CubicInterpolate(y, b.z, preA.z, postB.z, weight), + Mathf.CubicInterpolate(z, b.z, preA.z, postB.z, weight), Mathf.CubicInterpolate(w, b.w, preA.w, postB.w, weight) ); } @@ -212,7 +212,7 @@ namespace Godot ( Mathf.CubicInterpolateInTime(x, b.x, preA.x, postB.x, weight, t, preAT, postBT), Mathf.CubicInterpolateInTime(y, b.y, preA.y, postB.y, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(y, b.z, preA.z, postB.z, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(z, b.z, preA.z, postB.z, weight, t, preAT, postBT), Mathf.CubicInterpolateInTime(w, b.w, preA.w, postB.w, weight, t, preAT, postBT) ); } @@ -258,7 +258,7 @@ namespace Godot /// <returns>The dot product of the two vectors.</returns> public real_t Dot(Vector4 with) { - return (x * with.x) + (y * with.y) + (z * with.z) + (w + with.w); + return (x * with.x) + (y * with.y) + (z * with.z) + (w * with.w); } /// <summary> @@ -455,6 +455,7 @@ namespace Godot /// This can also be used to round to an arbitrary number of decimals. /// </summary> /// <param name="step">A vector value representing the step size to snap to.</param> + /// <returns>The snapped vector.</returns> public Vector4 Snapped(Vector4 step) { return new Vector4( @@ -632,6 +633,56 @@ namespace Godot } /// <summary> + /// Gets the remainder of each component of the <see cref="Vector4"/> + /// with the components of the given <see cref="real_t"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(real_t)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector4(10, -20, 30, 40) % 7); // Prints "(3, -6, 2, 5)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisor">The divisor value.</param> + /// <returns>The remainder vector.</returns> + public static Vector4 operator %(Vector4 vec, real_t divisor) + { + vec.x %= divisor; + vec.y %= divisor; + vec.z %= divisor; + vec.w %= divisor; + return vec; + } + + /// <summary> + /// Gets the remainder of each component of the <see cref="Vector4"/> + /// with the components of the given <see cref="Vector4"/>. + /// This operation uses truncated division, which is often not desired + /// as it does not work well with negative numbers. + /// Consider using <see cref="PosMod(Vector4)"/> instead + /// if you want to handle negative numbers. + /// </summary> + /// <example> + /// <code> + /// GD.Print(new Vector4(10, -20, 30, 10) % new Vector4(7, 8, 9, 10)); // Prints "(3, -4, 3, 0)" + /// </code> + /// </example> + /// <param name="vec">The dividend vector.</param> + /// <param name="divisorv">The divisor vector.</param> + /// <returns>The remainder vector.</returns> + public static Vector4 operator %(Vector4 vec, Vector4 divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + vec.z %= divisorv.z; + vec.w %= divisorv.w; + return vec; + } + + /// <summary> /// Returns <see langword="true"/> if the vectors are exactly equal. /// Note: Due to floating-point precision errors, consider using /// <see cref="IsEqualApprox"/> instead, which is more reliable. |