fix(input): dropped input handlers properly release methods
This commit is contained in:
@@ -129,6 +129,7 @@ impl InputMethod {
|
|||||||
self.handler_aliases.remove_aspect(handler);
|
self.handler_aliases.remove_aspect(handler);
|
||||||
self.handler_field_aliases
|
self.handler_field_aliases
|
||||||
.remove_aspect(handler.field.as_ref());
|
.remove_aspect(handler.field.as_ref());
|
||||||
|
self.capture_attempts.remove(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn serialize(&self, alias_id: u64, handler: &Arc<InputHandler>) -> InputData {
|
pub(super) fn serialize(&self, alias_id: u64, handler: &Arc<InputHandler>) -> InputData {
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ use crate::nodes::{
|
|||||||
spatial::Spatial,
|
spatial::Spatial,
|
||||||
};
|
};
|
||||||
use glam::vec3;
|
use glam::vec3;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CaptureManager {
|
pub struct CaptureManager {
|
||||||
pub capture: Option<Arc<InputHandler>>,
|
pub capture: Weak<InputHandler>,
|
||||||
}
|
}
|
||||||
impl CaptureManager {
|
impl CaptureManager {
|
||||||
pub fn update_capture(&mut self, method: &InputMethod) {
|
pub fn update_capture(&mut self, method: &InputMethod) {
|
||||||
if let Some(capture) = &self.capture {
|
if let Some(capture) = &self.capture.upgrade() {
|
||||||
if !method
|
if !method
|
||||||
.capture_attempts
|
.capture_attempts
|
||||||
.get_valid_contents()
|
.get_valid_contents()
|
||||||
.contains(capture)
|
.contains(capture)
|
||||||
{
|
{
|
||||||
self.capture.take();
|
self.capture = Weak::new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,13 +32,13 @@ impl CaptureManager {
|
|||||||
method: &InputMethod,
|
method: &InputMethod,
|
||||||
distance_calculator: DistanceCalculator,
|
distance_calculator: DistanceCalculator,
|
||||||
) {
|
) {
|
||||||
if self.capture.is_none() {
|
if self.capture.upgrade().is_none() {
|
||||||
self.capture = find_closest_capture(method, distance_calculator);
|
self.capture = find_closest_capture(method, distance_calculator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn apply_capture(&self, method: &InputMethod) {
|
pub fn apply_capture(&self, method: &InputMethod) {
|
||||||
method.captures.clear();
|
method.captures.clear();
|
||||||
if let Some(capture) = &self.capture {
|
if let Some(capture) = &self.capture.upgrade() {
|
||||||
method.set_handler_order([capture].into_iter());
|
method.set_handler_order([capture].into_iter());
|
||||||
method.captures.add_raw(capture);
|
method.captures.add_raw(capture);
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ type DistanceCalculator = fn(&Arc<Spatial>, &InputDataType, &Field) -> Option<f3
|
|||||||
pub fn find_closest_capture(
|
pub fn find_closest_capture(
|
||||||
method: &InputMethod,
|
method: &InputMethod,
|
||||||
distance_calculator: DistanceCalculator,
|
distance_calculator: DistanceCalculator,
|
||||||
) -> Option<Arc<InputHandler>> {
|
) -> Weak<InputHandler> {
|
||||||
method
|
method
|
||||||
.capture_attempts
|
.capture_attempts
|
||||||
.get_valid_contents()
|
.get_valid_contents()
|
||||||
@@ -60,7 +60,8 @@ pub fn find_closest_capture(
|
|||||||
.map(|dist| (h.clone(), dist))
|
.map(|dist| (h.clone(), dist))
|
||||||
})
|
})
|
||||||
.min_by(|(_, dist_a), (_, dist_b)| dist_a.partial_cmp(dist_b).unwrap())
|
.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(
|
pub fn get_sorted_handlers(
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ impl MousePointer {
|
|||||||
.set_new_capture(&self.pointer, distance_calculator);
|
.set_new_capture(&self.pointer, distance_calculator);
|
||||||
self.capture_manager.apply_capture(&self.pointer);
|
self.capture_manager.apply_capture(&self.pointer);
|
||||||
|
|
||||||
if self.capture_manager.capture.is_some() {
|
if self.capture_manager.capture.upgrade().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ impl SkController {
|
|||||||
controller.aim.position.into(),
|
controller.aim.position.into(),
|
||||||
);
|
);
|
||||||
self.material
|
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)
|
Color128::new_rgb(1.0, 1.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
Color128::new_rgb(0.0, 1.0, 0.75)
|
Color128::new_rgb(0.0, 1.0, 0.75)
|
||||||
@@ -128,7 +128,7 @@ impl SkController {
|
|||||||
.set_new_capture(&self.input, distance_calculator);
|
.set_new_capture(&self.input, distance_calculator);
|
||||||
self.capture_manager.apply_capture(&self.input);
|
self.capture_manager.apply_capture(&self.input);
|
||||||
|
|
||||||
if self.capture_manager.capture.is_some() {
|
if self.capture_manager.capture.upgrade().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ impl SkHand {
|
|||||||
|
|
||||||
hand.elbow = None;
|
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)
|
Color128::new_rgb(1.0, 1.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
Color128::new_rgb(0.0, 1.0, 0.75)
|
Color128::new_rgb(0.0, 1.0, 0.75)
|
||||||
@@ -174,7 +174,7 @@ impl SkHand {
|
|||||||
.set_new_capture(&self.input, distance_calculator);
|
.set_new_capture(&self.input, distance_calculator);
|
||||||
self.capture_manager.apply_capture(&self.input);
|
self.capture_manager.apply_capture(&self.input);
|
||||||
|
|
||||||
if self.capture_manager.capture.is_some() {
|
if self.capture_manager.capture.upgrade().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user