veloren_common_state/
special_areas.rs1use common::depot::{Depot, Id};
2use hashbrown::{HashMap, hash_map};
3use std::{
4 marker::PhantomData,
5 ops::{Deref, DerefMut},
6};
7use vek::*;
8
9#[derive(Default)]
10pub struct AreasContainer<Kind>(Areas, PhantomData<Kind>);
11
12#[derive(Default)]
13pub struct BuildArea;
14
15#[derive(Default)]
16pub struct NoDurabilityArea;
17
18#[derive(Default)]
22pub struct Areas {
23 areas: Depot<Aabb<i32>>,
24 area_names: HashMap<String, Id<Aabb<i32>>>,
25}
26
27pub enum SpecialAreaError {
28 Reserved,
30 NotFound,
32}
33
34const RESERVED_BUILD_AREA_NAMES: &[&str] = &["world"];
36
37impl Areas {
38 pub fn areas(&self) -> &Depot<Aabb<i32>> { &self.areas }
39
40 pub fn area_metas(&self) -> &HashMap<String, Id<Aabb<i32>>> { &self.area_names }
41
42 pub fn insert(&mut self, area_name: String, area: Aabb<i32>) -> Result<Id<Aabb<i32>>, String> {
44 let area_name_entry = match self.area_names.entry(area_name) {
45 hash_map::Entry::Occupied(o) => return Err(o.key().to_string()),
46 hash_map::Entry::Vacant(v) => v,
47 };
48 let bb_id = self.areas.insert(area.made_valid());
49 area_name_entry.insert(bb_id);
50 Ok(bb_id)
51 }
52
53 pub fn remove(&mut self, area_name: &str) -> Result<Aabb<i32>, SpecialAreaError> {
54 if RESERVED_BUILD_AREA_NAMES.contains(&area_name) {
55 return Err(SpecialAreaError::Reserved);
56 }
57 let bb_id = self
58 .area_names
59 .remove(area_name)
60 .ok_or(SpecialAreaError::NotFound)?;
61 let area = self.areas.remove(bb_id).expect(
62 "Entries in `areas` are added before entries in `area_names` in `insert`, and that is \
63 the only exposed way to add elements to `area_names`.",
64 );
65 Ok(area)
66 }
67}
68
69impl<Kind> Deref for AreasContainer<Kind>
70where
71 Kind: AreaKind,
72{
73 type Target = Areas;
74
75 fn deref(&self) -> &Self::Target { &self.0 }
76}
77
78impl<Kind> DerefMut for AreasContainer<Kind>
79where
80 Kind: AreaKind,
81{
82 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
83}
84
85pub trait AreaKind {
86 fn display() -> &'static str;
87}
88
89impl AreaKind for BuildArea {
90 fn display() -> &'static str { "build" }
91}
92
93impl AreaKind for NoDurabilityArea {
94 fn display() -> &'static str { "durability free" }
95}