1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
use crate::{application::ChangeNotifier, messenger::MessageData, props::PropsData, Prefab}; use serde::{Deserialize, Serialize}; use std::sync::{Arc, RwLock}; #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct DataBinding<T> where T: std::fmt::Debug + Default + Send + Sync, { #[serde(skip)] data: Arc<RwLock<T>>, #[serde(skip)] notifier: Option<ChangeNotifier>, } impl<T> DataBinding<T> where T: std::fmt::Debug + Default + Send + Sync, { pub fn new(data: T) -> Self { Self { data: Arc::new(RwLock::new(data)), notifier: None, } } pub fn new_bound(data: T, notifier: ChangeNotifier) -> Self { Self { data: Arc::new(RwLock::new(data)), notifier: Some(notifier), } } pub fn bind(&mut self, notifier: ChangeNotifier) { self.notifier = Some(notifier); } pub fn unbind(&mut self) { self.notifier = None; } pub fn access<F, R>(&self, mut f: F) -> Option<R> where F: FnMut(&T) -> R, { if let Ok(data) = self.data.read() { Some(f(&data)) } else { None } } pub fn read_cloned(&self) -> Option<T> where T: Clone, { if let Ok(data) = self.data.read() { let data: &T = &data; Some(data.clone()) } else { None } } pub fn read_cloned_or_default(&self) -> T where T: Clone, { self.read_cloned().unwrap_or_default() } pub fn mutate<F, R>(&mut self, mut f: F) -> Option<R> where F: FnMut(&mut T) -> R, { if let Ok(mut data) = self.data.write() { let result = f(&mut data); if let Some(notifier) = self.notifier.as_mut() { notifier.change(); } Some(result) } else { None } } pub fn write(&mut self, v: T) { if let Ok(mut data) = self.data.write() { *data = v; if let Some(notifier) = self.notifier.as_mut() { notifier.change(); } } } } impl<T> PropsData for DataBinding<T> where Self: Clone, T: 'static + std::fmt::Debug + Default + Send + Sync, { fn clone_props(&self) -> Box<dyn PropsData> { Box::new(self.clone()) } fn as_any(&self) -> &dyn std::any::Any { self } } impl<T> Prefab for DataBinding<T> where T: std::fmt::Debug + Default + Send + Sync {} impl<T> MessageData for DataBinding<T> where Self: Clone, T: 'static + std::fmt::Debug + Default + Send + Sync, { fn clone_message(&self) -> Box<dyn MessageData> { Box::new(self.clone()) } fn as_any(&self) -> &dyn std::any::Any { self } }