perspective_viewer/utils/
debounce.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use std::cell::Cell;
14use std::future::Future;
15use std::rc::Rc;
16
17use async_lock::Mutex;
18use perspective_js::utils::ApiResult;
19
20#[derive(Default)]
21pub struct DebounceMutexData {
22    id: Cell<u64>,
23    mutex: Mutex<u64>,
24}
25
26#[derive(Clone, Default)]
27pub struct DebounceMutex(Rc<DebounceMutexData>);
28
29impl DebounceMutex {
30    pub async fn lock<T>(&self, f: impl Future<Output = T>) -> T {
31        let mut last = self.0.mutex.lock().await;
32        let next = self.0.id.get();
33        let result = f.await;
34        *last = next;
35        result
36    }
37
38    pub async fn debounce(&self, f: impl Future<Output = ApiResult<()>>) -> ApiResult<()> {
39        let next = self.0.id.get() + 1;
40        let mut last = self.0.mutex.lock().await;
41        if *last < next {
42            let next = self.0.id.get() + 1;
43            self.0.id.set(next);
44            let result = f.await;
45            if result.is_ok() {
46                *last = next;
47            }
48
49            result
50        } else {
51            Ok(())
52        }
53    }
54}