gioser

tawasuyu/mirada

Sovereign tiling Wayland compositor + window manager in Rust, on Llimphi.

Rust 50Markdown 30TOML 211282 Definitions

⎇ main vendor/smithay/src/utils/iter.rs Rust · 71 lines · 2.0 KB History Who touched what raw

chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0) a91da3fea · Sergio ·

1/// Common iterator types
2use wayland_server::{backend::ClientId, Resource, Weak};
3
4use std::{fmt, sync::MutexGuard};
5
6/// Iterator helper over a mutex of client objects
7pub struct LockedClientObjsIter<'a, T: 'static, G, F> {
8    pub iterator: std::iter::FilterMap<std::slice::Iter<'static, Weak<T>>, F>,
9    pub guard: MutexGuard<'a, G>,
10}
11
12pub(crate) fn new_locked_obj_iter_from_vec<T: Resource + 'static>(
13    guard: MutexGuard<'_, Vec<Weak<T>>>,
14    client: ClientId,
15) -> impl Iterator<Item = T> + '_ {
16    new_locked_obj_iter(guard, client, |guard| guard.iter())
17}
18
19pub(crate) fn new_locked_obj_iter<
20    'a,
21    T: Resource + 'static,
22    G,
23    F: for<'b> FnOnce(&'b G) -> std::slice::Iter<'b, Weak<T>>,
24>(
25    guard: MutexGuard<'a, G>,
26    client: ClientId,
27    iterator_fn: F,
28) -> impl Iterator<Item = T> + 'a {
29    let iterator = unsafe {
30        std::mem::transmute::<std::slice::Iter<'_, Weak<T>>, std::slice::Iter<'static, Weak<T>>>(iterator_fn(
31            &*guard,
32        ))
33    };
34
35    let iterator = iterator.filter_map(move |p| {
36        let client = &client;
37        p.upgrade()
38            .ok()
39            .filter(|p| p.client().is_some_and(|c| c.id() == *client))
40    });
41
42    LockedClientObjsIter::<'a, T, G, _>::new_internal(iterator, guard)
43}
44
45impl<'a, T, G, F> LockedClientObjsIter<'a, T, G, F> {
46    fn new_internal(
47        iterator: std::iter::FilterMap<std::slice::Iter<'static, Weak<T>>, F>,
48        guard: MutexGuard<'a, G>,
49    ) -> Self {
50        LockedClientObjsIter { iterator, guard }
51    }
52}
53
54impl<T, G, F> Iterator for LockedClientObjsIter<'_, T, G, F>
55where
56    F: FnMut(&'static Weak<T>) -> Option<T>,
57{
58    type Item = T;
59
60    fn next(&mut self) -> Option<Self::Item> {
61        self.iterator.next()
62    }
63}
64
65impl<T, G: fmt::Debug, F> fmt::Debug for LockedClientObjsIter<'_, T, G, F> {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        f.debug_struct("LockedClientObjsIter")
68            .field("inner", &self.guard)
69            .finish()
70    }
71}