Make statehandle a weak reference

This commit is contained in:
hodasemi 2024-04-05 11:13:08 +02:00
parent 8599d7bb0e
commit 9e28804a38

View file

@ -5,7 +5,7 @@ use assetpath::AssetPath;
use std::any::Any; use std::any::Any;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock, Weak};
pub trait FutureStateChange: Fn() -> Result<()> + Send + Sync { pub trait FutureStateChange: Fn() -> Result<()> + Send + Sync {
fn clone_box<'a>(&self) -> Box<dyn 'a + FutureStateChange> fn clone_box<'a>(&self) -> Box<dyn 'a + FutureStateChange>
@ -45,74 +45,88 @@ struct State {
/// only used for updating callbacks /// only used for updating callbacks
#[derive(Clone)] #[derive(Clone)]
pub struct StateHandle { pub struct StateHandle {
state: Arc<State>, state: Weak<State>,
} }
impl StateHandle { impl StateHandle {
pub fn update<'a>(&self, update_type: StateUpdateType<'a>) -> Result<()> { pub fn update<'a>(&self, update_type: StateUpdateType<'a>) -> Result<()> {
self.state.update(update_type) self.state.upgrade().unwrap().update(update_type)
} }
} }
impl GetElement<Button> for StateHandle { impl GetElement<Button> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<Button>> { fn element(&self, id: &str) -> Result<Arc<Button>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<Grid> for StateHandle { impl GetElement<Grid> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<Grid>> { fn element(&self, id: &str) -> Result<Arc<Grid>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<Label> for StateHandle { impl GetElement<Label> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<Label>> { fn element(&self, id: &str) -> Result<Arc<Label>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<TextField> for StateHandle { impl GetElement<TextField> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<TextField>> { fn element(&self, id: &str) -> Result<Arc<TextField>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<MultiLineTextField> for StateHandle { impl GetElement<MultiLineTextField> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<MultiLineTextField>> { fn element(&self, id: &str) -> Result<Arc<MultiLineTextField>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<Icon> for StateHandle { impl GetElement<Icon> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<Icon>> { fn element(&self, id: &str) -> Result<Arc<Icon>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
impl GetElement<ProgressBar> for StateHandle { impl GetElement<ProgressBar> for StateHandle {
fn element(&self, id: &str) -> Result<Arc<ProgressBar>> { fn element(&self, id: &str) -> Result<Arc<ProgressBar>> {
match self.state.top_level_gui.elements() { let state = self.state.upgrade().unwrap();
match state.top_level_gui.elements() {
Some(elements) => elements.element(id), Some(elements) => elements.element(id),
None => panic!("state ({}) has no elements", self.state.name), None => panic!("state ({}) has no elements", state.name),
} }
} }
} }
@ -302,7 +316,7 @@ impl States {
/// Retrieve a StateHandle /// Retrieve a StateHandle
pub fn state_handle(&self, id: &str) -> Result<StateHandle> { pub fn state_handle(&self, id: &str) -> Result<StateHandle> {
Ok(StateHandle { Ok(StateHandle {
state: self.get_state(id)?, state: Arc::downgrade(&self.get_state(id)?),
}) })
} }