Optimization: introduce IdMap
This commit is contained in:
parent
5799758c2b
commit
4dcdd014d6
6 changed files with 63 additions and 18 deletions
|
@ -1,10 +1,8 @@
|
|||
use epaint::ahash::AHashMap;
|
||||
|
||||
use crate::{emath::remap_clamp, Id, InputState};
|
||||
use crate::{emath::remap_clamp, Id, IdMap, InputState};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct AnimationManager {
|
||||
bools: AHashMap<Id, BoolAnim>,
|
||||
bools: IdMap<BoolAnim>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::*;
|
||||
use epaint::ahash;
|
||||
|
||||
/// State that is collected during a frame and then cleared.
|
||||
/// Short-term (single frame) memory.
|
||||
|
@ -7,7 +6,7 @@ use epaint::ahash;
|
|||
pub(crate) struct FrameState {
|
||||
/// All `Id`s that were used this frame.
|
||||
/// Used to debug `Id` clashes of widgets.
|
||||
pub(crate) used_ids: ahash::AHashMap<Id, Rect>,
|
||||
pub(crate) used_ids: IdMap<Rect>,
|
||||
|
||||
/// Starts off as the screen_rect, shrinks as panels are added.
|
||||
/// The `CentralPanel` does not change this.
|
||||
|
|
|
@ -67,3 +67,56 @@ impl std::fmt::Debug for Id {
|
|||
write!(f, "{:X}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Idea taken from the `nohash_hasher` crate.
|
||||
#[derive(Default)]
|
||||
pub struct IdHasher(u64);
|
||||
|
||||
impl std::hash::Hasher for IdHasher {
|
||||
fn write(&mut self, _: &[u8]) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
|
||||
fn write_u8(&mut self, _n: u8) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_u16(&mut self, _n: u16) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_u32(&mut self, _n: u32) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_u64(&mut self, n: u64) {
|
||||
self.0 = n
|
||||
}
|
||||
fn write_usize(&mut self, _n: usize) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
|
||||
fn write_i8(&mut self, _n: i8) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_i16(&mut self, _n: i16) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_i32(&mut self, _n: i32) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_i64(&mut self, _n: i64) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
fn write_isize(&mut self, _n: isize) {
|
||||
unreachable!("Invalid use of IdHasher")
|
||||
}
|
||||
|
||||
fn finish(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub type BuilIdHasher = std::hash::BuildHasherDefault<IdHasher>;
|
||||
|
||||
/// `IdMap<V>` is a `HashMap<Id, V>` optimized by knowing that `Id` has good entropy, and doesn't need more hashing.
|
||||
pub type IdMap<V> = std::collections::HashMap<Id, V, BuilIdHasher>;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//! are sometimes painted behind or in front of other things.
|
||||
|
||||
use crate::{Id, *};
|
||||
use epaint::ahash::AHashMap;
|
||||
use epaint::mutex::Mutex;
|
||||
use epaint::{ClippedShape, Shape};
|
||||
use std::sync::Arc;
|
||||
|
@ -154,7 +153,7 @@ impl PaintList {
|
|||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct GraphicLayers([AHashMap<Id, Arc<Mutex<PaintList>>>; Order::COUNT]);
|
||||
pub(crate) struct GraphicLayers([IdMap<Arc<Mutex<PaintList>>>; Order::COUNT]);
|
||||
|
||||
impl GraphicLayers {
|
||||
pub fn list(&mut self, layer_id: LayerId) -> &Arc<Mutex<PaintList>> {
|
||||
|
|
|
@ -387,7 +387,7 @@ pub use {
|
|||
output::{self, CursorIcon, Output, WidgetInfo},
|
||||
},
|
||||
grid::Grid,
|
||||
id::Id,
|
||||
id::{Id, IdMap},
|
||||
input_state::{InputState, MultiTouchInfo, PointerState},
|
||||
layers::{LayerId, Order},
|
||||
layout::*,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{any, area, window, Id, InputState, LayerId, Pos2, Rect, Style};
|
||||
use crate::{any, area, window, Id, IdMap, InputState, LayerId, Pos2, Rect, Style};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -259,7 +259,7 @@ impl Focus {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn end_frame(&mut self, used_ids: &epaint::ahash::AHashMap<Id, Rect>) {
|
||||
pub(crate) fn end_frame(&mut self, used_ids: &IdMap<Rect>) {
|
||||
if let Some(id) = self.id {
|
||||
// Allow calling `request_focus` one frame and not using it until next frame
|
||||
let recently_gained_focus = self.id_previous_frame != Some(id);
|
||||
|
@ -310,11 +310,7 @@ impl Memory {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn end_frame(
|
||||
&mut self,
|
||||
input: &InputState,
|
||||
used_ids: &epaint::ahash::AHashMap<Id, Rect>,
|
||||
) {
|
||||
pub(crate) fn end_frame(&mut self, input: &InputState, used_ids: &IdMap<Rect>) {
|
||||
self.caches.update();
|
||||
self.areas.end_frame();
|
||||
self.interaction.focus.end_frame(used_ids);
|
||||
|
@ -465,7 +461,7 @@ impl Memory {
|
|||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub struct Areas {
|
||||
areas: HashMap<Id, area::State>,
|
||||
areas: IdMap<area::State>,
|
||||
/// Back-to-front. Top is last.
|
||||
order: Vec<LayerId>,
|
||||
visible_last_frame: HashSet<LayerId>,
|
||||
|
|
Loading…
Reference in a new issue