Skip to content

Commit 98ed184

Browse files
committed
fix: prevent ropes from automatically disconnecting when switching editor scenes
1 parent 633577e commit 98ed184

File tree

4 files changed

+38
-22
lines changed

4 files changed

+38
-22
lines changed

stag-toolkit/src/classes/island.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
use crate::classes::island_settings::IslandBuilderSettings;
22
use crate::math::bounding_box::BoundingBox;
33
use crate::mesh::island::{Data, IslandBuilderSettingsTweaks, SettingsTweaks};
4+
use crate::mesh::trimesh::TriangleMesh;
45
use crate::{
56
classes::utils::editor_lock,
67
math::types::ToVector3,
78
mesh::godot::{GodotSurfaceArrays, GodotWhitebox},
89
};
910
use core::f32;
10-
use std::thread;
11-
use std::thread::JoinHandle;
1211
use glam::Vec3;
1312
use godot::classes::{Engine, ImporterMesh, ResourceLoader};
1413
use godot::register::ConnectHandle;
@@ -19,7 +18,8 @@ use godot::{
1918
},
2019
prelude::*,
2120
};
22-
use crate::mesh::trimesh::TriangleMesh;
21+
use std::thread;
22+
use std::thread::JoinHandle;
2323

2424
/// The node group IslandBuilder nodes should be stored in.
2525
pub const GROUP_NAME: &str = "StagToolkit_IslandBuilder";
@@ -115,10 +115,10 @@ impl INode3D for IslandBuilder {
115115
}
116116

117117
fn process(&mut self, _delta: f64) {
118-
if let Some(preview_thread) = &self.realtime_preview_thread {
119-
if preview_thread.is_finished() {
120-
self.wait_for_preview_finish(); // join preview if it's done
121-
}
118+
if let Some(preview_thread) = &self.realtime_preview_thread
119+
&& preview_thread.is_finished()
120+
{
121+
self.wait_for_preview_finish(); // join preview if it's done
122122
}
123123
}
124124
}
@@ -219,7 +219,8 @@ impl IslandBuilder {
219219
#[func]
220220
fn set_realtime_preview(&mut self, realtime_preview: bool) {
221221
self.realtime_preview = realtime_preview;
222-
self.base_mut().set_process(realtime_preview && Engine::singleton().is_editor_hint());
222+
self.base_mut()
223+
.set_process(realtime_preview && Engine::singleton().is_editor_hint());
223224

224225
// Wait for any existing preview to finish before moving on
225226
self.wait_for_preview_finish();
@@ -231,7 +232,7 @@ impl IslandBuilder {
231232

232233
fn wait_for_preview_finish(&mut self) {
233234
if let Some(handle) = self.realtime_preview_thread.take() {
234-
let data = handle.join().unwrap();
235+
let data = handle.join().expect("realtime preview thread panicked");
235236
if let Some(trimesh) = data {
236237
// Fetch previously stored buffer and clear it for use, or create a new one
237238
let buffer_mesh: Gd<ArrayMesh> = match self.realtime_preview_mesh_buffer.take() {
@@ -263,7 +264,12 @@ impl IslandBuilder {
263264
}
264265
}
265266

266-
fn apply_preview_mesh(&mut self, mut mesh_node: Gd<MeshInstance3D>, mut array_mesh: Gd<ArrayMesh>, trimesh: &TriangleMesh) {
267+
fn apply_preview_mesh(
268+
&mut self,
269+
mut mesh_node: Gd<MeshInstance3D>,
270+
mut array_mesh: Gd<ArrayMesh>,
271+
trimesh: &TriangleMesh,
272+
) {
267273
let surface_arrays = GodotSurfaceArrays::from_trimesh(trimesh);
268274
array_mesh.add_surface_from_arrays(
269275
PrimitiveType::TRIANGLES,

stag-toolkit/src/classes/rope.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -850,14 +850,17 @@ impl SimulatedRopeBinding {
850850
if let Some(rope) = new_bind_to {
851851
self.signals().rope_bound().emit(&rope);
852852

853-
// Automatically remove rope if it is removed from tree
854-
self.event_rope_tree_exiting = Some(
855-
rope.signals()
856-
.tree_exiting()
857-
.builder()
858-
.flags(ConnectFlags::ONE_SHOT)
859-
.connect_other_mut(&self.to_gd(), Self::clear_bind),
860-
);
853+
// Automatically remove rope if it is removed from tree.
854+
// Note: DO NOT disconnect the binding automatically if the rope is exiting the tree inside the editor!
855+
if !Engine::singleton().is_editor_hint() {
856+
self.event_rope_tree_exiting = Some(
857+
rope.signals()
858+
.tree_exiting()
859+
.builder()
860+
.flags(ConnectFlags::ONE_SHOT)
861+
.connect_other_mut(&self.to_gd(), Self::clear_bind),
862+
);
863+
}
861864
}
862865
}
863866

@@ -900,7 +903,9 @@ impl SimulatedRopeBinding {
900903
/// Updates the bind settings on this [SimulatedRopeBinding]'s corresponding rope.
901904
#[func]
902905
fn update_bind(&mut self) {
903-
if let Some(mut rope) = self.bind_to.clone() {
906+
if let Some(mut rope) = self.bind_to.clone()
907+
&& rope.is_inside_tree()
908+
{
904909
let pos = rope.to_local(self.base().get_global_position());
905910
rope.bind_mut()
906911
.bind_set(self.get_bind_id(), pos, self.bind_at);

stag-toolkit/src/mesh/island.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,11 @@ impl Data {
494494
let (mut voxels, transform) = self.bake_voxels_init();
495495

496496
#[cfg(debug_assertions)]
497-
assert_ne!(0, voxels.get_buffer_size(), "voxel buffer size is zero, did you bake a bounding box?");
497+
assert_ne!(
498+
0,
499+
voxels.get_buffer_size(),
500+
"voxel buffer size is zero, did you bake a bounding box?"
501+
);
498502

499503
let mut voxel_workers = voxels.to_workers(
500504
utils::worker_count(voxels.get_buffer_size(), 16usize).get(),

stag-toolkit/src/utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ pub fn thread_count(default_thread_count: usize) -> NonZero<usize> {
88
default_thread_count, 0,
99
"default thread count cannot be zero"
1010
);
11-
available_parallelism()
12-
.unwrap_or_else(|_| NonZero::new(default_thread_count).expect("zero-value default thread count provided"))
11+
available_parallelism().unwrap_or_else(|_| {
12+
NonZero::new(default_thread_count).expect("zero-value default thread count provided")
13+
})
1314
}
1415

1516
/// Returns the number of workers desired for the given workload size.

0 commit comments

Comments
 (0)