From 624e709a8f524560a7f42cdcad31bfdfc2578c7f Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 17 Apr 2020 23:44:14 +0200 Subject: [PATCH] Make Id a proper newtype --- emigui/src/emigui.rs | 2 +- emigui/src/id.rs | 29 +++++++++++++++++++++++++++++ emigui/src/layout.rs | 16 ++-------------- emigui/src/lib.rs | 4 +++- emigui/src/region.rs | 14 ++------------ emigui/src/widgets.rs | 9 ++++++--- emigui/src/window.rs | 10 +++------- 7 files changed, 46 insertions(+), 38 deletions(-) create mode 100644 emigui/src/id.rs diff --git a/emigui/src/emigui.rs b/emigui/src/emigui.rs index 318b10ae..505eecc4 100644 --- a/emigui/src/emigui.rs +++ b/emigui/src/emigui.rs @@ -45,7 +45,7 @@ impl Emigui { ctx: self.ctx.clone(), layer: Layer::Background, style: self.ctx.style(), - id: Default::default(), + id: Id::whole_screen(), dir: layout::Direction::Vertical, align: layout::Align::Center, cursor: Default::default(), diff --git a/emigui/src/id.rs b/emigui/src/id.rs new file mode 100644 index 00000000..8a25d354 --- /dev/null +++ b/emigui/src/id.rs @@ -0,0 +1,29 @@ +use std::{collections::hash_map::DefaultHasher, hash::Hash}; + +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] +pub struct Id(u64); + +impl Id { + pub fn whole_screen() -> Self { + Self(0) + } + + pub fn popup() -> Self { + Self(1) + } + + pub fn new(source: &H) -> Id { + use std::hash::Hasher; + let mut hasher = DefaultHasher::new(); + source.hash(&mut hasher); + Id(hasher.finish()) + } + + pub fn with(self, child: &H) -> Id { + use std::hash::Hasher; + let mut hasher = DefaultHasher::new(); + hasher.write_u64(self.0); + child.hash(&mut hasher); + Id(hasher.finish()) + } +} diff --git a/emigui/src/layout.rs b/emigui/src/layout.rs index bc56908b..ed62b00b 100644 --- a/emigui/src/layout.rs +++ b/emigui/src/layout.rs @@ -1,4 +1,4 @@ -use std::{hash::Hash, sync::Arc}; +use std::sync::Arc; use crate::{widgets::*, *}; @@ -80,18 +80,6 @@ impl Default for Align { // ---------------------------------------------------------------------------- -// TODO: newtype -pub type Id = u64; - -pub fn make_id(source: &H) -> Id { - use std::hash::Hasher; - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - source.hash(&mut hasher); - hasher.finish() -} - -// ---------------------------------------------------------------------------- - /// Show a pop-over window pub fn show_popup(ctx: &Arc, window_pos: Vec2, add_contents: F) where @@ -107,7 +95,7 @@ where ctx: ctx.clone(), layer, style, - id: Default::default(), + id: Id::popup(), dir: Direction::Vertical, align: Align::Min, cursor: window_pos + window_padding, diff --git a/emigui/src/lib.rs b/emigui/src/lib.rs index e0255e19..2ba8580b 100644 --- a/emigui/src/lib.rs +++ b/emigui/src/lib.rs @@ -12,6 +12,7 @@ mod emigui; pub mod example_app; mod font; mod fonts; +mod id; mod layers; mod layout; pub mod math; @@ -29,8 +30,9 @@ pub use { color::Color, context::Context, fonts::{FontDefinitions, Fonts, TextStyle}, + id::Id, layers::*, - layout::{Align, Id}, + layout::Align, math::*, memory::Memory, mesher::{Mesh, Vertex}, diff --git a/emigui/src/region.rs b/emigui/src/region.rs index f4765c81..6fdf2869 100644 --- a/emigui/src/region.rs +++ b/emigui/src/region.rs @@ -359,21 +359,11 @@ impl Region { } pub fn make_child_id(&self, child_id: &H) -> Id { - use std::hash::Hasher; - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - hasher.write_u64(self.id); - child_id.hash(&mut hasher); - hasher.finish() + self.id.with(child_id) } pub fn combined_id(&self, child_id: Option) -> Option { - child_id.map(|child_id| { - use std::hash::Hasher; - let mut hasher = std::collections::hash_map::DefaultHasher::new(); - hasher.write_u64(self.id); - child_id.hash(&mut hasher); - hasher.finish() - }) + child_id.map(|child_id| self.id.with(&child_id)) } // Helper function diff --git a/emigui/src/widgets.rs b/emigui/src/widgets.rs index 0ad26964..7b0e3140 100644 --- a/emigui/src/widgets.rs +++ b/emigui/src/widgets.rs @@ -1,7 +1,7 @@ #![allow(clippy::new_without_default_derive)] use crate::{ - layout::{make_id, Direction, GuiResponse}, + layout::{Direction, GuiResponse}, *, }; @@ -351,7 +351,7 @@ impl<'a> Widget for Slider<'a> { let text_color = self.text_color; let value = (self.get_set_value)(None); let full_text = format!("{}: {:.*}", text, self.precision, value); - let id = Some(self.id.unwrap_or_else(|| make_id(text))); + let id = Some(self.id.unwrap_or_else(|| Id::new(text))); let mut naked = self; naked.id = id; naked.text = None; @@ -379,7 +379,10 @@ impl<'a> Widget for Slider<'a> { let min = self.min; let max = self.max; debug_assert!(min <= max); - let id = region.combined_id(Some(self.id.unwrap_or(42))); // TODO: slider ID + let id = region.combined_id(Some( + self.id + .expect("Sliders must have a text label or an explicit id"), + )); let interact = region.reserve_space( Vec2 { x: region.available_space.x, diff --git a/emigui/src/window.rs b/emigui/src/window.rs index 0f1488c7..e22caae0 100644 --- a/emigui/src/window.rs +++ b/emigui/src/window.rs @@ -1,10 +1,6 @@ use std::sync::Arc; -use crate::{ - layout::{make_id, Direction}, - widgets::Label, - *, -}; +use crate::{layout::Direction, widgets::Label, *}; #[derive(Clone, Copy, Debug)] pub struct WindowState { @@ -28,7 +24,7 @@ impl Window { where F: FnOnce(&mut Region), { - let id = make_id(&self.title); + let id = Id::new(&self.title); let mut state = ctx.memory.lock().get_or_create_window( id, @@ -48,7 +44,7 @@ impl Window { ctx: ctx.clone(), layer, style, - id: Default::default(), + id, dir: Direction::Vertical, align: Align::Min, cursor: state.rect.min() + window_padding,