reactive_graph/signal/
arc_trigger.rs

1use super::subscriber_traits::AsSubscriberSet;
2use crate::{
3    graph::{ReactiveNode, SubscriberSet},
4    traits::{DefinedAt, IsDisposed, Notify, Track},
5};
6use std::{
7    fmt::{Debug, Formatter, Result},
8    panic::Location,
9    sync::{Arc, RwLock},
10};
11
12/// A trigger is a data-less signal with the sole purpose of notifying other reactive code of a change.
13///
14/// This can be useful for when using external data not stored in signals, for example.
15pub struct ArcTrigger {
16    #[cfg(any(debug_assertions, leptos_debuginfo))]
17    pub(crate) defined_at: &'static Location<'static>,
18    pub(crate) inner: Arc<RwLock<SubscriberSet>>,
19}
20
21impl ArcTrigger {
22    /// Creates a new trigger.
23    #[track_caller]
24    pub fn new() -> Self {
25        Self {
26            #[cfg(any(debug_assertions, leptos_debuginfo))]
27            defined_at: Location::caller(),
28            inner: Default::default(),
29        }
30    }
31}
32
33impl Default for ArcTrigger {
34    fn default() -> Self {
35        Self::new()
36    }
37}
38
39impl Clone for ArcTrigger {
40    #[track_caller]
41    fn clone(&self) -> Self {
42        Self {
43            #[cfg(any(debug_assertions, leptos_debuginfo))]
44            defined_at: self.defined_at,
45            inner: Arc::clone(&self.inner),
46        }
47    }
48}
49
50impl Debug for ArcTrigger {
51    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
52        f.debug_struct("ArcTrigger").finish()
53    }
54}
55
56impl IsDisposed for ArcTrigger {
57    #[inline(always)]
58    fn is_disposed(&self) -> bool {
59        false
60    }
61}
62
63impl AsSubscriberSet for ArcTrigger {
64    type Output = Arc<RwLock<SubscriberSet>>;
65
66    #[inline(always)]
67    fn as_subscriber_set(&self) -> Option<Self::Output> {
68        Some(Arc::clone(&self.inner))
69    }
70}
71
72impl Notify for Vec<ArcTrigger> {
73    fn notify(&self) {
74        for trigger in self {
75            trigger.notify();
76        }
77    }
78}
79
80impl Track for Vec<ArcTrigger> {
81    fn track(&self) {
82        for trigger in self {
83            trigger.track();
84        }
85    }
86}
87
88impl DefinedAt for ArcTrigger {
89    #[inline(always)]
90    fn defined_at(&self) -> Option<&'static Location<'static>> {
91        #[cfg(any(debug_assertions, leptos_debuginfo))]
92        {
93            Some(self.defined_at)
94        }
95        #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
96        {
97            None
98        }
99    }
100}
101
102impl Notify for ArcTrigger {
103    fn notify(&self) {
104        self.inner.mark_dirty();
105    }
106}