diff --git a/src/nodes/input/method.rs b/src/nodes/input/method.rs index c7fb645..a736d70 100644 --- a/src/nodes/input/method.rs +++ b/src/nodes/input/method.rs @@ -129,6 +129,7 @@ impl InputMethod { self.handler_aliases.remove_aspect(handler); self.handler_field_aliases .remove_aspect(handler.field.as_ref()); + self.capture_attempts.remove(handler); } pub(super) fn serialize(&self, alias_id: u64, handler: &Arc) -> InputData { diff --git a/src/objects/input/mod.rs b/src/objects/input/mod.rs index 3209e53..36ab8ce 100644 --- a/src/objects/input/mod.rs +++ b/src/objects/input/mod.rs @@ -9,21 +9,21 @@ use crate::nodes::{ spatial::Spatial, }; use glam::vec3; -use std::sync::Arc; +use std::sync::{Arc, Weak}; #[derive(Default)] pub struct CaptureManager { - pub capture: Option>, + pub capture: Weak, } impl CaptureManager { pub fn update_capture(&mut self, method: &InputMethod) { - if let Some(capture) = &self.capture { + if let Some(capture) = &self.capture.upgrade() { if !method .capture_attempts .get_valid_contents() .contains(capture) { - self.capture.take(); + self.capture = Weak::new(); } } } @@ -32,13 +32,13 @@ impl CaptureManager { method: &InputMethod, distance_calculator: DistanceCalculator, ) { - if self.capture.is_none() { + if self.capture.upgrade().is_none() { self.capture = find_closest_capture(method, distance_calculator); } } pub fn apply_capture(&self, method: &InputMethod) { method.captures.clear(); - if let Some(capture) = &self.capture { + if let Some(capture) = &self.capture.upgrade() { method.set_handler_order([capture].into_iter()); method.captures.add_raw(capture); } @@ -50,7 +50,7 @@ type DistanceCalculator = fn(&Arc, &InputDataType, &Field) -> Option Option> { +) -> Weak { method .capture_attempts .get_valid_contents() @@ -60,7 +60,8 @@ pub fn find_closest_capture( .map(|dist| (h.clone(), dist)) }) .min_by(|(_, dist_a), (_, dist_b)| dist_a.partial_cmp(dist_b).unwrap()) - .map(|(handler, _)| handler) + .map(|(handler, _)| Arc::downgrade(&handler)) + .unwrap_or_default() } pub fn get_sorted_handlers( diff --git a/src/objects/input/mouse_pointer.rs b/src/objects/input/mouse_pointer.rs index 48e30e0..79cca22 100644 --- a/src/objects/input/mouse_pointer.rs +++ b/src/objects/input/mouse_pointer.rs @@ -142,7 +142,7 @@ impl MousePointer { .set_new_capture(&self.pointer, distance_calculator); self.capture_manager.apply_capture(&self.pointer); - if self.capture_manager.capture.is_some() { + if self.capture_manager.capture.upgrade().is_some() { return; } diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index f60e06a..14f579c 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -96,7 +96,7 @@ impl SkController { controller.aim.position.into(), ); self.material - .color_tint(if self.capture_manager.capture.is_none() { + .color_tint(if self.capture_manager.capture.upgrade().is_none() { Color128::new_rgb(1.0, 1.0, 1.0) } else { Color128::new_rgb(0.0, 1.0, 0.75) @@ -128,7 +128,7 @@ impl SkController { .set_new_capture(&self.input, distance_calculator); self.capture_manager.apply_capture(&self.input); - if self.capture_manager.capture.is_some() { + if self.capture_manager.capture.upgrade().is_some() { return; } diff --git a/src/objects/input/sk_hand.rs b/src/objects/input/sk_hand.rs index 95e2adc..1e32721 100644 --- a/src/objects/input/sk_hand.rs +++ b/src/objects/input/sk_hand.rs @@ -140,7 +140,7 @@ impl SkHand { hand.elbow = None; - let hand_color = if self.capture_manager.capture.is_none() { + let hand_color = if self.capture_manager.capture.upgrade().is_none() { Color128::new_rgb(1.0, 1.0, 1.0) } else { Color128::new_rgb(0.0, 1.0, 0.75) @@ -174,7 +174,7 @@ impl SkHand { .set_new_capture(&self.input, distance_calculator); self.capture_manager.apply_capture(&self.input); - if self.capture_manager.capture.is_some() { + if self.capture_manager.capture.upgrade().is_some() { return; }