/* wearechat - generic multiplayer game with voip Copyright (C) 2025 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use egui::Widget; use std::{ collections::{HashMap, HashSet}, hash::Hash, sync::RwLock, }; pub struct DemandMap { inner: RwLock>, } struct DemandMapState { values: HashMap, needed: HashSet, size_metric: usize, } impl DemandMap { pub fn new() -> Self { Self { inner: DemandMapState { needed: HashSet::new(), values: HashMap::new(), size_metric: 0, } .into(), } } pub fn needed(&self) -> Vec { self.inner.read().unwrap().needed.iter().cloned().collect() } pub fn insert(&self, key: K, value: V, size: usize) { let mut s = self.inner.write().unwrap(); s.needed.remove(&key); s.values.insert(key, value); s.size_metric += size; } pub fn try_get(&self, key: K) -> Option { let mut s = self.inner.write().unwrap(); if let Some(k) = s.values.get(&key) { Some(k.to_owned()) } else { s.needed.insert(key); None } } } impl Widget for &DemandMap { fn ui(self, ui: &mut egui::Ui) -> egui::Response { let state = self.inner.read().unwrap(); ui.label(state.needed.len().to_string()); ui.label(state.values.len().to_string()); ui.label(humansize::format_size( state.size_metric, humansize::DECIMAL, )); ui.end_row(); ui.response() } }