glassy_ui/motion/
values.rs1use std::collections::HashMap;
2use std::sync::{Arc, RwLock};
3
4use gpui::{App, Global, SharedString};
5
6#[derive(Clone)]
8pub struct MotionValue {
9 name: SharedString,
10 store: Arc<RwLock<HashMap<SharedString, f32>>>,
11}
12
13impl MotionValue {
14 pub fn get(&self) -> f32 {
15 self.store
16 .read()
17 .ok()
18 .and_then(|map| map.get(&self.name).copied())
19 .unwrap_or(0.0)
20 }
21
22 pub fn set(&self, value: f32) {
23 if let Ok(mut map) = self.store.write() {
24 map.insert(self.name.clone(), value);
25 }
26 }
27
28 pub fn set_with_notify(&self, value: f32, cx: &mut App) {
30 self.set(value);
31 cx.refresh_windows();
32 }
33
34 pub fn name(&self) -> &SharedString {
35 &self.name
36 }
37}
38
39pub struct MotionValueStore {
41 values: Arc<RwLock<HashMap<SharedString, f32>>>,
42}
43
44impl Global for MotionValueStore {}
45
46impl MotionValueStore {
47 pub fn init(cx: &mut App) {
48 if !cx.has_global::<Self>() {
49 cx.set_global(Self {
50 values: Arc::new(RwLock::new(HashMap::new())),
51 });
52 }
53 }
54}
55
56pub fn init(cx: &mut App) {
57 MotionValueStore::init(cx);
58}
59
60pub fn use_motion_value(cx: &App, name: impl Into<SharedString>) -> MotionValue {
62 let name = name.into();
63 let store = if cx.has_global::<MotionValueStore>() {
64 cx.global::<MotionValueStore>().values.clone()
65 } else {
66 Arc::new(RwLock::new(HashMap::new()))
68 };
69 {
70 let mut map = store.write().expect("motion value store poisoned");
71 map.entry(name.clone()).or_insert(0.0);
72 }
73 MotionValue { name, store }
74}