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, IdMap, InputState};
|
||||||
|
|
||||||
use crate::{emath::remap_clamp, Id, InputState};
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub(crate) struct AnimationManager {
|
pub(crate) struct AnimationManager {
|
||||||
bools: AHashMap<Id, BoolAnim>,
|
bools: IdMap<BoolAnim>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use epaint::ahash;
|
|
||||||
|
|
||||||
/// State that is collected during a frame and then cleared.
|
/// State that is collected during a frame and then cleared.
|
||||||
/// Short-term (single frame) memory.
|
/// Short-term (single frame) memory.
|
||||||
|
@ -7,7 +6,7 @@ use epaint::ahash;
|
||||||
pub(crate) struct FrameState {
|
pub(crate) struct FrameState {
|
||||||
/// All `Id`s that were used this frame.
|
/// All `Id`s that were used this frame.
|
||||||
/// Used to debug `Id` clashes of widgets.
|
/// 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.
|
/// Starts off as the screen_rect, shrinks as panels are added.
|
||||||
/// The `CentralPanel` does not change this.
|
/// The `CentralPanel` does not change this.
|
||||||
|
|
|
@ -67,3 +67,56 @@ impl std::fmt::Debug for Id {
|
||||||
write!(f, "{:X}", self.0)
|
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.
|
//! are sometimes painted behind or in front of other things.
|
||||||
|
|
||||||
use crate::{Id, *};
|
use crate::{Id, *};
|
||||||
use epaint::ahash::AHashMap;
|
|
||||||
use epaint::mutex::Mutex;
|
use epaint::mutex::Mutex;
|
||||||
use epaint::{ClippedShape, Shape};
|
use epaint::{ClippedShape, Shape};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -154,7 +153,7 @@ impl PaintList {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[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 {
|
impl GraphicLayers {
|
||||||
pub fn list(&mut self, layer_id: LayerId) -> &Arc<Mutex<PaintList>> {
|
pub fn list(&mut self, layer_id: LayerId) -> &Arc<Mutex<PaintList>> {
|
||||||
|
|
|
@ -387,7 +387,7 @@ pub use {
|
||||||
output::{self, CursorIcon, Output, WidgetInfo},
|
output::{self, CursorIcon, Output, WidgetInfo},
|
||||||
},
|
},
|
||||||
grid::Grid,
|
grid::Grid,
|
||||||
id::Id,
|
id::{Id, IdMap},
|
||||||
input_state::{InputState, MultiTouchInfo, PointerState},
|
input_state::{InputState, MultiTouchInfo, PointerState},
|
||||||
layers::{LayerId, Order},
|
layers::{LayerId, Order},
|
||||||
layout::*,
|
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 {
|
if let Some(id) = self.id {
|
||||||
// Allow calling `request_focus` one frame and not using it until next frame
|
// Allow calling `request_focus` one frame and not using it until next frame
|
||||||
let recently_gained_focus = self.id_previous_frame != Some(id);
|
let recently_gained_focus = self.id_previous_frame != Some(id);
|
||||||
|
@ -310,11 +310,7 @@ impl Memory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn end_frame(
|
pub(crate) fn end_frame(&mut self, input: &InputState, used_ids: &IdMap<Rect>) {
|
||||||
&mut self,
|
|
||||||
input: &InputState,
|
|
||||||
used_ids: &epaint::ahash::AHashMap<Id, Rect>,
|
|
||||||
) {
|
|
||||||
self.caches.update();
|
self.caches.update();
|
||||||
self.areas.end_frame();
|
self.areas.end_frame();
|
||||||
self.interaction.focus.end_frame(used_ids);
|
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", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
pub struct Areas {
|
pub struct Areas {
|
||||||
areas: HashMap<Id, area::State>,
|
areas: IdMap<area::State>,
|
||||||
/// Back-to-front. Top is last.
|
/// Back-to-front. Top is last.
|
||||||
order: Vec<LayerId>,
|
order: Vec<LayerId>,
|
||||||
visible_last_frame: HashSet<LayerId>,
|
visible_last_frame: HashSet<LayerId>,
|
||||||
|
|
Loading…
Reference in a new issue