dvcompute/simulation/
ref_comp.rs1use std::cell::UnsafeCell;
8use std::ptr;
9
10use crate::simulation;
11use crate::simulation::point::Point;
12use crate::simulation::event::Event;
13
14use dvcompute_utils::grc::Grc;
15
16pub struct RefComp<T> {
18
19 cell: UnsafeCell<T>
21}
22
23impl<T> RefComp<T> {
24
25 #[inline]
27 pub fn new(val: T) -> RefComp<T> {
28 RefComp { cell: UnsafeCell::new(val) }
29 }
30
31 #[inline]
33 pub fn read_at(&self, _p: &Point) -> T
34 where T: Clone
35 {
36 let p = self.cell.get();
37 unsafe {
38 (*p).clone()
39 }
40 }
41
42 #[inline]
44 pub fn read(comp: Grc<Self>) -> Read<T>
45 where T: Clone
46 {
47 Read { comp: comp }
48 }
49
50 #[inline]
52 pub fn swap_at(&self, val: T, _p: &Point) -> T {
53 let mut t = val;
54 unsafe {
55 ptr::swap(&mut t, self.cell.get());
56 }
57 t
58 }
59
60 #[inline]
62 pub fn swap(comp: Grc<Self>, val: T) -> Swap<T> {
63 Swap { comp: comp, val: val }
64 }
65
66 #[inline]
68 pub fn write_at(&self, val: T, _p: &Point) {
69 let p = self.cell.get();
70 unsafe {
71 *p = val;
72 }
73 }
74
75 #[inline]
77 pub fn write(comp: Grc<Self>, val: T) -> Write<T> {
78 Write { comp: comp, val: val }
79 }
80
81 #[inline]
83 pub fn modify_at<F>(&self, f: F, _p: &Point)
84 where F: FnOnce(&T) -> T,
85 T: Clone
86 {
87 let p = self.cell.get();
88 unsafe {
89 let t = (*p).clone();
90 *p = f(&t);
91 }
92 }
93
94 #[inline]
96 pub fn modify<F>(comp: Grc<Self>, f: F) -> Modify<T, F>
97 where F: FnOnce(&T) -> T,
98 T: Clone
99 {
100 Modify { comp: comp, f: f }
101 }
102}
103
104impl<T> PartialEq for RefComp<T> {
105
106 fn eq(&self, other: &Self) -> bool {
107 self.cell.get() == other.cell.get()
108 }
109}
110
111impl<T> Eq for RefComp<T> {}
112
113impl<T: Clone> Clone for RefComp<T> {
114
115 fn clone(&self) -> Self {
116 let p = self.cell.get();
117 unsafe {
118 let val = (*p).clone();
119 RefComp { cell: UnsafeCell::new(val) }
120 }
121 }
122}
123
124#[must_use = "computations are lazy and do nothing unless to be run"]
126#[derive(Clone)]
127pub struct Read<T> where T: 'static {
128
129 comp: Grc<RefComp<T>>
131}
132
133impl<T: Clone> Event for Read<T> {
134
135 type Item = T;
136
137 #[inline]
138 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
139 let Read { comp } = self;
140 Result::Ok(comp.read_at(p))
141 }
142}
143
144#[must_use = "computations are lazy and do nothing unless to be run"]
146#[derive(Clone)]
147pub struct Swap<T> where T: 'static {
148
149 comp: Grc<RefComp<T>>,
151
152 val: T
154}
155
156impl<T> Event for Swap<T> {
157
158 type Item = T;
159
160 #[inline]
161 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
162 let Swap { comp, val } = self;
163 Result::Ok(comp.swap_at(val, p))
164 }
165}
166
167#[must_use = "computations are lazy and do nothing unless to be run"]
169#[derive(Clone)]
170pub struct Write<T> where T: 'static {
171
172 comp: Grc<RefComp<T>>,
174
175 val: T
177}
178
179impl<T> Event for Write<T> {
180
181 type Item = ();
182
183 #[inline]
184 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
185 let Write { comp, val } = self;
186 Result::Ok(comp.write_at(val, p))
187 }
188}
189
190#[must_use = "computations are lazy and do nothing unless to be run"]
192#[derive(Clone)]
193pub struct Modify<T, F> where T: 'static {
194
195 comp: Grc<RefComp<T>>,
197
198 f: F
200}
201
202impl<T, F> Event for Modify<T, F>
203 where F: FnOnce(&T) -> T,
204 T: Clone
205{
206 type Item = ();
207
208 #[inline]
209 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
210 let Modify { comp, f } = self;
211 Result::Ok(comp.modify_at(f, p))
212 }
213}