1#![allow(clippy::upper_case_acronyms)]
6#![allow(clippy::from_over_into)]
7
8#[macro_use]
9extern crate memoffset;
10#[macro_use]
11extern crate lazy_static;
12
13pub use arrayvec;
14pub use byteorder;
15pub use nalgebra as algebra;
16pub use num_traits;
17pub use parking_lot;
18pub use rand;
19pub use uuid;
20
21use crate::visitor::{Visit, VisitResult, Visitor};
22use fxhash::FxHashMap;
23use std::ffi::OsString;
24use std::{
25 borrow::Borrow,
26 hash::Hash,
27 path::{Path, PathBuf},
28};
29
30pub mod color;
31pub mod color_gradient;
32pub mod curve;
33pub mod inspect;
34pub mod io;
35pub mod math;
36pub mod numeric_range;
37pub mod octree;
38pub mod pool;
39pub mod profiler;
40pub mod quadtree;
41pub mod rectpack;
42pub mod sparse;
43pub mod sstorage;
44pub mod visitor;
45
46pub use futures;
47pub use instant;
48
49#[cfg(target_arch = "wasm32")]
50pub use js_sys;
51use std::iter::FromIterator;
52#[cfg(target_arch = "wasm32")]
53pub use wasm_bindgen;
54#[cfg(target_arch = "wasm32")]
55pub use wasm_bindgen_futures;
56#[cfg(target_arch = "wasm32")]
57pub use web_sys;
58
59#[macro_export]
61macro_rules! define_is_as {
62 ($typ:tt : $kind:ident -> ref $result:path => fn $is:ident, fn $as_ref:ident, fn $as_mut:ident) => {
63 pub fn $is(&self) -> bool {
65 match self {
66 $typ::$kind(_) => true,
67 _ => false,
68 }
69 }
70
71 pub fn $as_ref(&self) -> &$result {
74 match self {
75 $typ::$kind(ref val) => val,
76 _ => panic!("Cast to {} failed!", stringify!($kind)),
77 }
78 }
79
80 pub fn $as_mut(&mut self) -> &mut $result {
83 match self {
84 $typ::$kind(ref mut val) => val,
85 _ => panic!("Cast to {} failed!", stringify!($kind)),
86 }
87 }
88 };
89}
90
91pub fn replace_slashes<P: AsRef<Path>>(path: P) -> PathBuf {
94 #[cfg(target_os = "windows")]
95 {
96 if path.as_ref().is_absolute() {
97 path.as_ref().to_owned()
100 } else {
101 let mut os_str = std::ffi::OsString::new();
104 let count = path.as_ref().components().count();
105 for (i, component) in path.as_ref().components().enumerate() {
106 os_str.push(component.as_os_str());
107 if i != count - 1 {
108 os_str.push("/");
109 }
110 }
111 PathBuf::from(os_str)
112 }
113 }
114
115 #[cfg(not(target_os = "windows"))]
116 {
117 path.as_ref().to_owned()
118 }
119}
120
121#[must_use]
133pub fn append_extension<P: AsRef<Path>, E: AsRef<str>>(
134 path: P,
135 additional_extension: E,
136) -> PathBuf {
137 let mut final_path = path.as_ref().to_path_buf();
138 let new_extension = final_path
139 .extension()
140 .map(|e| {
141 let mut ext = e.to_owned();
142 ext.push(".");
143 ext.push(additional_extension.as_ref());
144 ext
145 })
146 .unwrap_or_else(|| OsString::from(additional_extension.as_ref()));
147 final_path.set_extension(new_extension);
148 final_path
149}
150
151#[derive(Clone, Debug)]
152pub struct BiDirHashMap<K, V> {
153 forward_map: FxHashMap<K, V>,
154 backward_map: FxHashMap<V, K>,
155}
156
157impl<K: Hash + Eq + Clone, V: Hash + Eq + Clone> BiDirHashMap<K, V> {
158 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
159 let existing = self.forward_map.insert(key.clone(), value.clone());
160 self.backward_map.insert(value, key);
161 existing
162 }
163
164 pub fn remove_by_key(&mut self, key: &K) -> Option<V> {
165 if let Some(value) = self.forward_map.remove(key) {
166 self.backward_map.remove(&value);
167 Some(value)
168 } else {
169 None
170 }
171 }
172
173 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
174 where
175 K: Borrow<Q>,
176 Q: Hash + Eq,
177 {
178 self.forward_map.contains_key(key)
179 }
180
181 pub fn remove_by_value(&mut self, value: &V) -> Option<K> {
182 if let Some(key) = self.backward_map.remove(value) {
183 self.forward_map.remove(&key);
184 Some(key)
185 } else {
186 None
187 }
188 }
189
190 pub fn contains_value<Q: ?Sized>(&self, value: &Q) -> bool
191 where
192 V: Borrow<Q>,
193 Q: Hash + Eq,
194 {
195 self.backward_map.contains_key(value)
196 }
197
198 pub fn value_of(&self, node: &K) -> Option<&V> {
199 self.forward_map.get(node)
200 }
201
202 pub fn key_of(&self, value: &V) -> Option<&K> {
203 self.backward_map.get(value)
204 }
205
206 pub fn len(&self) -> usize {
207 self.forward_map.len()
208 }
209
210 pub fn is_empty(&self) -> bool {
211 self.forward_map.is_empty()
212 }
213
214 pub fn clear(&mut self) {
215 self.forward_map.clear();
216 self.backward_map.clear();
217 }
218
219 pub fn forward_map(&self) -> &FxHashMap<K, V> {
220 &self.forward_map
221 }
222
223 pub fn backward_map(&self) -> &FxHashMap<V, K> {
224 &self.backward_map
225 }
226
227 pub fn into_inner(self) -> (FxHashMap<K, V>, FxHashMap<V, K>) {
228 (self.forward_map, self.backward_map)
229 }
230}
231
232impl<K, V> Default for BiDirHashMap<K, V> {
233 fn default() -> Self {
234 Self {
235 forward_map: Default::default(),
236 backward_map: Default::default(),
237 }
238 }
239}
240
241impl<K: Hash + Eq + Clone, V: Hash + Eq + Clone> From<FxHashMap<K, V>> for BiDirHashMap<K, V> {
242 fn from(forward_map: FxHashMap<K, V>) -> Self {
243 let mut backward_map = FxHashMap::default();
244 for (k, v) in forward_map.iter() {
245 backward_map.insert(v.clone(), k.clone());
246 }
247 Self {
248 forward_map,
249 backward_map,
250 }
251 }
252}
253
254impl<K, V> Visit for BiDirHashMap<K, V>
255where
256 K: Hash + Eq + Clone + Default + Visit,
257 V: Hash + Eq + Clone + Default + Visit,
258{
259 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
260 visitor.enter_region(name)?;
261
262 self.forward_map.visit("ForwardMap", visitor)?;
263 self.backward_map.visit("BackwardMap", visitor)?;
264
265 visitor.leave_region()
266 }
267}
268
269impl<K, V> FromIterator<(K, V)> for BiDirHashMap<K, V>
270where
271 K: Hash + Eq + Clone,
272 V: Hash + Eq + Clone,
273{
274 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
275 let mut hm = Self::default();
276 for (k, v) in iter {
277 hm.forward_map.insert(k.clone(), v.clone());
278 hm.backward_map.insert(v, k);
279 }
280 hm
281 }
282}
283
284pub trait VecExtensions<T> {
285 fn retain_mut_ext<F>(&mut self, f: F)
296 where
297 F: FnMut(&mut T) -> bool;
298}
299
300impl<T> VecExtensions<T> for Vec<T> {
301 fn retain_mut_ext<F>(&mut self, mut f: F)
302 where
303 F: FnMut(&mut T) -> bool,
304 {
305 let len = self.len();
306 let mut del = 0;
307 {
308 let v = &mut **self;
309
310 for i in 0..len {
311 if !f(&mut v[i]) {
312 del += 1;
313 } else if del > 0 {
314 v.swap(i - del, i);
315 }
316 }
317 }
318 if del > 0 {
319 self.truncate(len - del);
320 }
321 }
322}
323
324#[inline]
325pub fn hash_combine(lhs: u64, rhs: u64) -> u64 {
326 lhs ^ (rhs
327 .wrapping_add(0x9e3779b9)
328 .wrapping_add(lhs << 6)
329 .wrapping_add(lhs >> 2))
330}