utils: Add macro for global ids

This commit is contained in:
Victor Brekenfeld 2022-01-04 18:28:39 +01:00
parent 61b19e4198
commit 3674daf083
5 changed files with 43 additions and 84 deletions

View File

@ -16,38 +16,12 @@ use wayland_server::protocol::wl_surface::WlSurface;
use std::{
cell::{RefCell, RefMut},
collections::HashSet,
hash::{Hash, Hasher},
rc::Rc,
sync::{
atomic::{AtomicUsize, Ordering},
Arc, Mutex, Weak,
},
sync::{Arc, Mutex, Weak},
};
// TODO: Should this be a macro?
static LAYER_ID: AtomicUsize = AtomicUsize::new(0);
lazy_static::lazy_static! {
static ref LAYER_IDS: Mutex<HashSet<usize>> = Mutex::new(HashSet::new());
}
fn next_layer_id() -> usize {
let mut ids = LAYER_IDS.lock().unwrap();
if ids.len() == usize::MAX {
// Theoretically the code below wraps around correctly,
// but that is hard to detect and might deadlock.
// Maybe make this a debug_assert instead?
panic!("Out of window ids");
}
let mut id = LAYER_ID.fetch_add(1, Ordering::SeqCst);
while ids.iter().any(|k| *k == id) {
id = LAYER_ID.fetch_add(1, Ordering::SeqCst);
}
ids.insert(id);
id
}
crate::utils::ids::id_gen!(next_layer_id, LAYER_ID, LAYER_IDS);
#[derive(Debug)]
pub struct LayerMap {

View File

@ -15,14 +15,7 @@ use crate::{
},
};
use indexmap::{IndexMap, IndexSet};
use std::{
cell::RefCell,
collections::{HashSet, VecDeque},
sync::{
atomic::{AtomicUsize, Ordering},
Mutex,
},
};
use std::{cell::RefCell, collections::VecDeque};
use wayland_server::protocol::wl_surface::WlSurface;
mod element;
@ -35,27 +28,7 @@ use self::layer::*;
use self::output::*;
use self::window::*;
static SPACE_ID: AtomicUsize = AtomicUsize::new(0);
lazy_static::lazy_static! {
static ref SPACE_IDS: Mutex<HashSet<usize>> = Mutex::new(HashSet::new());
}
fn next_space_id() -> usize {
let mut ids = SPACE_IDS.lock().unwrap();
if ids.len() == usize::MAX {
// Theoretically the code below wraps around correctly,
// but that is hard to detect and might deadlock.
// Maybe make this a debug_assert instead?
panic!("Out of space ids");
}
let mut id = SPACE_ID.fetch_add(1, Ordering::SeqCst);
while ids.iter().any(|k| *k == id) {
id = SPACE_ID.fetch_add(1, Ordering::SeqCst);
}
ids.insert(id);
id
}
crate::utils::ids::id_gen!(next_space_id, SPACE_ID, SPACE_IDS);
// TODO: Maybe replace UnmanagedResource if nothing else comes up?
#[derive(Debug, thiserror::Error)]

View File

@ -10,40 +10,14 @@ use crate::{
};
use std::{
cell::Cell,
collections::HashSet,
hash::{Hash, Hasher},
rc::Rc,
sync::{
atomic::{AtomicUsize, Ordering},
Mutex,
},
};
use wayland_commons::user_data::UserDataMap;
use wayland_protocols::xdg_shell::server::xdg_toplevel;
use wayland_server::protocol::wl_surface;
static WINDOW_ID: AtomicUsize = AtomicUsize::new(0);
lazy_static::lazy_static! {
static ref WINDOW_IDS: Mutex<HashSet<usize>> = Mutex::new(HashSet::new());
}
fn next_window_id() -> usize {
let mut ids = WINDOW_IDS.lock().unwrap();
if ids.len() == usize::MAX {
// Theoretically the code below wraps around correctly,
// but that is hard to detect and might deadlock.
// Maybe make this a debug_assert instead?
panic!("Out of window ids");
}
let mut id = WINDOW_ID.fetch_add(1, Ordering::SeqCst);
while ids.iter().any(|k| *k == id) {
id = WINDOW_ID.fetch_add(1, Ordering::SeqCst);
}
ids.insert(id);
id
}
crate::utils::ids::id_gen!(next_window_id, WINDOW_ID, WINDOW_IDS);
#[derive(Debug, Clone, PartialEq)]
pub enum Kind {

37
src/utils/ids.rs Normal file
View File

@ -0,0 +1,37 @@
macro_rules! id_gen {
($func_name:ident, $id_name:ident, $ids_name:ident) => {
static $id_name: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
lazy_static::lazy_static! {
static ref $ids_name: std::sync::Mutex<std::collections::HashSet<usize>> =
std::sync::Mutex::new(std::collections::HashSet::new());
}
fn $func_name() -> usize {
let mut ids = $ids_name.lock().unwrap();
if ids.len() == usize::MAX {
panic!("Out of ids");
}
let id = loop {
let new_id = $id_name.fetch_update(
std::sync::atomic::Ordering::SeqCst,
std::sync::atomic::Ordering::SeqCst,
|mut id| {
while ids.iter().any(|k| *k == id) {
id += 1;
}
Some(id)
},
);
if let Ok(id) = new_id {
break id;
}
};
ids.insert(id);
id
}
};
}
pub(crate) use id_gen;

View File

@ -6,6 +6,7 @@ pub mod signaling;
#[cfg(feature = "x11rb_event_source")]
pub mod x11rb;
pub(crate) mod ids;
pub mod user_data;
pub use self::geometry::{Buffer, Coordinate, Logical, Physical, Point, Raw, Rectangle, Size};