1
0

lib.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. #![doc = include_str!("../README.md")]
  2. #![warn(missing_docs)]
  3. use std::{
  4. any::Any,
  5. cell::{Cell, Ref, RefCell, RefMut},
  6. error::Error,
  7. fmt::{Debug, Display},
  8. marker::PhantomData,
  9. ops::{Deref, DerefMut},
  10. rc::Rc,
  11. };
  12. use bumpalo::Bump;
  13. /// # Example
  14. ///
  15. /// ```compile_fail
  16. /// let data = String::from("hello world");
  17. /// let store = Store::default();
  18. /// let owner = store.owner();
  19. /// let key = owner.insert(&data);
  20. /// drop(data);
  21. /// assert_eq!(*key.read(), "hello world");
  22. /// ```
  23. #[allow(unused)]
  24. fn compile_fail() {}
  25. #[test]
  26. fn reused() {
  27. let store = Store::default();
  28. let first_ptr;
  29. {
  30. let owner = store.owner();
  31. first_ptr = owner.insert(1).raw.0.data.as_ptr();
  32. drop(owner);
  33. }
  34. {
  35. let owner = store.owner();
  36. let second_ptr = owner.insert(1234).raw.0.data.as_ptr();
  37. assert_eq!(first_ptr, second_ptr);
  38. drop(owner);
  39. }
  40. }
  41. #[test]
  42. fn leaking_is_ok() {
  43. let data = String::from("hello world");
  44. let store = Store::default();
  45. let key;
  46. {
  47. // create an owner
  48. let owner = store.owner();
  49. // insert data into the store
  50. key = owner.insert(data);
  51. // don't drop the owner
  52. std::mem::forget(owner);
  53. }
  54. assert_eq!(
  55. key.try_read().as_deref().unwrap(),
  56. &"hello world".to_string()
  57. );
  58. }
  59. #[test]
  60. fn drops() {
  61. let data = String::from("hello world");
  62. let store = Store::default();
  63. let key;
  64. {
  65. // create an owner
  66. let owner = store.owner();
  67. // insert data into the store
  68. key = owner.insert(data);
  69. // drop the owner
  70. }
  71. assert!(key.try_read().is_err());
  72. }
  73. #[test]
  74. fn works() {
  75. let store = Store::default();
  76. let owner = store.owner();
  77. let key = owner.insert(1);
  78. assert_eq!(*key.read(), 1);
  79. }
  80. #[test]
  81. fn insert_while_reading() {
  82. let store = Store::default();
  83. let owner = store.owner();
  84. let key;
  85. {
  86. let data: String = "hello world".to_string();
  87. key = owner.insert(data);
  88. }
  89. let value = key.read();
  90. owner.insert(&1);
  91. assert_eq!(*value, "hello world");
  92. }
  93. #[test]
  94. #[should_panic]
  95. fn panics() {
  96. let store = Store::default();
  97. let owner = store.owner();
  98. let key = owner.insert(1);
  99. drop(owner);
  100. assert_eq!(*key.read(), 1);
  101. }
  102. #[test]
  103. fn fuzz() {
  104. fn maybe_owner_scope(
  105. store: &Store,
  106. valid_keys: &mut Vec<GenerationalBox<String>>,
  107. invalid_keys: &mut Vec<GenerationalBox<String>>,
  108. path: &mut Vec<u8>,
  109. ) {
  110. let branch_cutoff = 5;
  111. let children = if path.len() < branch_cutoff {
  112. rand::random::<u8>() % 4
  113. } else {
  114. rand::random::<u8>() % 2
  115. };
  116. for i in 0..children {
  117. let owner = store.owner();
  118. let key = owner.insert(format!("hello world {path:?}"));
  119. valid_keys.push(key);
  120. path.push(i);
  121. // read all keys
  122. println!("{:?}", path);
  123. for key in valid_keys.iter() {
  124. let value = key.read();
  125. println!("{:?}", &*value);
  126. assert!(value.starts_with("hello world"));
  127. }
  128. #[cfg(any(debug_assertions, feature = "check_generation"))]
  129. for key in invalid_keys.iter() {
  130. assert!(!key.validate());
  131. }
  132. maybe_owner_scope(store, valid_keys, invalid_keys, path);
  133. invalid_keys.push(valid_keys.pop().unwrap());
  134. path.pop();
  135. }
  136. }
  137. for _ in 0..10 {
  138. let store = Store::default();
  139. maybe_owner_scope(&store, &mut Vec::new(), &mut Vec::new(), &mut Vec::new());
  140. }
  141. }
  142. /// The core Copy state type. The generational box will be dropped when the [Owner] is dropped.
  143. pub struct GenerationalBox<T> {
  144. raw: MemoryLocation,
  145. #[cfg(any(debug_assertions, feature = "check_generation"))]
  146. generation: u32,
  147. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  148. created_at: &'static std::panic::Location<'static>,
  149. _marker: PhantomData<T>,
  150. }
  151. impl<T: 'static> Debug for GenerationalBox<T> {
  152. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  153. #[cfg(any(debug_assertions, feature = "check_generation"))]
  154. f.write_fmt(format_args!(
  155. "{:?}@{:?}",
  156. self.raw.0.data.as_ptr(),
  157. self.generation
  158. ))?;
  159. #[cfg(not(any(debug_assertions, feature = "check_generation")))]
  160. f.write_fmt(format_args!("{:?}", self.raw.data.as_ptr()))?;
  161. Ok(())
  162. }
  163. }
  164. impl<T: 'static> GenerationalBox<T> {
  165. #[inline(always)]
  166. fn validate(&self) -> bool {
  167. #[cfg(any(debug_assertions, feature = "check_generation"))]
  168. {
  169. self.raw.0.generation.get() == self.generation
  170. }
  171. #[cfg(not(any(debug_assertions, feature = "check_generation")))]
  172. {
  173. true
  174. }
  175. }
  176. /// Try to read the value. Returns None if the value is no longer valid.
  177. #[track_caller]
  178. pub fn try_read(&self) -> Result<GenerationalRef<T>, BorrowError> {
  179. if !self.validate() {
  180. return Err(BorrowError::Dropped(ValueDroppedError {
  181. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  182. created_at: self.created_at,
  183. }));
  184. }
  185. self.raw.try_borrow(
  186. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  187. self.created_at,
  188. )
  189. }
  190. /// Read the value. Panics if the value is no longer valid.
  191. #[track_caller]
  192. pub fn read(&self) -> GenerationalRef<T> {
  193. self.try_read().unwrap()
  194. }
  195. /// Try to write the value. Returns None if the value is no longer valid.
  196. #[track_caller]
  197. pub fn try_write(&self) -> Result<GenerationalRefMut<T>, BorrowMutError> {
  198. if !self.validate() {
  199. return Err(BorrowMutError::Dropped(ValueDroppedError {
  200. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  201. created_at: self.created_at,
  202. }));
  203. }
  204. self.raw.try_borrow_mut(
  205. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  206. self.created_at,
  207. )
  208. }
  209. /// Write the value. Panics if the value is no longer valid.
  210. #[track_caller]
  211. pub fn write(&self) -> GenerationalRefMut<T> {
  212. self.try_write().unwrap()
  213. }
  214. /// Set the value. Panics if the value is no longer valid.
  215. pub fn set(&self, value: T) {
  216. self.validate().then(|| {
  217. *self.raw.0.data.borrow_mut() = Some(Box::new(value));
  218. });
  219. }
  220. /// Returns true if the pointer is equal to the other pointer.
  221. pub fn ptr_eq(&self, other: &Self) -> bool {
  222. #[cfg(any(debug_assertions, feature = "check_generation"))]
  223. {
  224. self.raw.0.data.as_ptr() == other.raw.0.data.as_ptr()
  225. && self.generation == other.generation
  226. }
  227. #[cfg(not(any(debug_assertions, feature = "check_generation")))]
  228. {
  229. self.raw.data.as_ptr() == other.raw.data.as_ptr()
  230. }
  231. }
  232. }
  233. impl<T> Copy for GenerationalBox<T> {}
  234. impl<T> Clone for GenerationalBox<T> {
  235. fn clone(&self) -> Self {
  236. *self
  237. }
  238. }
  239. #[derive(Clone, Copy)]
  240. struct MemoryLocation(&'static MemoryLocationInner);
  241. struct MemoryLocationInner {
  242. data: RefCell<Option<Box<dyn std::any::Any>>>,
  243. #[cfg(any(debug_assertions, feature = "check_generation"))]
  244. generation: Cell<u32>,
  245. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  246. borrowed_at: RefCell<Vec<&'static std::panic::Location<'static>>>,
  247. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  248. borrowed_mut_at: Cell<Option<&'static std::panic::Location<'static>>>,
  249. }
  250. impl MemoryLocation {
  251. #[allow(unused)]
  252. fn drop(&self) {
  253. let old = self.0.data.borrow_mut().take();
  254. #[cfg(any(debug_assertions, feature = "check_generation"))]
  255. if old.is_some() {
  256. drop(old);
  257. let new_generation = self.0.generation.get() + 1;
  258. self.0.generation.set(new_generation);
  259. }
  260. }
  261. fn replace_with_caller<T: 'static>(
  262. &mut self,
  263. value: T,
  264. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  265. caller: &'static std::panic::Location<'static>,
  266. ) -> GenerationalBox<T> {
  267. let mut inner_mut = self.0.data.borrow_mut();
  268. let raw = Box::new(value);
  269. let old = inner_mut.replace(raw);
  270. assert!(old.is_none());
  271. GenerationalBox {
  272. raw: *self,
  273. #[cfg(any(debug_assertions, feature = "check_generation"))]
  274. generation: self.0.generation.get(),
  275. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  276. created_at: caller,
  277. _marker: PhantomData,
  278. }
  279. }
  280. #[track_caller]
  281. fn try_borrow<T: Any>(
  282. &self,
  283. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  284. created_at: &'static std::panic::Location<'static>,
  285. ) -> Result<GenerationalRef<T>, BorrowError> {
  286. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  287. self.0
  288. .borrowed_at
  289. .borrow_mut()
  290. .push(std::panic::Location::caller());
  291. match self.0.data.try_borrow() {
  292. Ok(borrow) => match Ref::filter_map(borrow, |any| any.as_ref()?.downcast_ref::<T>()) {
  293. Ok(reference) => Ok(GenerationalRef {
  294. inner: reference,
  295. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  296. borrow: GenerationalRefBorrowInfo {
  297. borrowed_at: std::panic::Location::caller(),
  298. borrowed_from: self.0,
  299. },
  300. }),
  301. Err(_) => Err(BorrowError::Dropped(ValueDroppedError {
  302. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  303. created_at,
  304. })),
  305. },
  306. Err(_) => Err(BorrowError::AlreadyBorrowedMut(AlreadyBorrowedMutError {
  307. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  308. borrowed_mut_at: self.0.borrowed_mut_at.get().unwrap(),
  309. })),
  310. }
  311. }
  312. #[track_caller]
  313. fn try_borrow_mut<T: Any>(
  314. &self,
  315. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  316. created_at: &'static std::panic::Location<'static>,
  317. ) -> Result<GenerationalRefMut<T>, BorrowMutError> {
  318. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  319. {
  320. self.0
  321. .borrowed_mut_at
  322. .set(Some(std::panic::Location::caller()));
  323. }
  324. match self.0.data.try_borrow_mut() {
  325. Ok(borrow_mut) => {
  326. match RefMut::filter_map(borrow_mut, |any| any.as_mut()?.downcast_mut::<T>()) {
  327. Ok(reference) => Ok(GenerationalRefMut {
  328. inner: reference,
  329. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  330. borrow: GenerationalRefMutBorrowInfo {
  331. borrowed_from: self.0,
  332. },
  333. }),
  334. Err(_) => Err(BorrowMutError::Dropped(ValueDroppedError {
  335. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  336. created_at,
  337. })),
  338. }
  339. }
  340. Err(_) => Err(BorrowMutError::AlreadyBorrowed(AlreadyBorrowedError {
  341. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  342. borrowed_at: self.0.borrowed_at.borrow().clone(),
  343. })),
  344. }
  345. }
  346. }
  347. #[derive(Debug, Clone)]
  348. /// An error that can occur when trying to borrow a value.
  349. pub enum BorrowError {
  350. /// The value was dropped.
  351. Dropped(ValueDroppedError),
  352. /// The value was already borrowed mutably.
  353. AlreadyBorrowedMut(AlreadyBorrowedMutError),
  354. }
  355. impl Display for BorrowError {
  356. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  357. match self {
  358. BorrowError::Dropped(error) => Display::fmt(error, f),
  359. BorrowError::AlreadyBorrowedMut(error) => Display::fmt(error, f),
  360. }
  361. }
  362. }
  363. impl Error for BorrowError {}
  364. #[derive(Debug, Clone)]
  365. /// An error that can occur when trying to borrow a value mutably.
  366. pub enum BorrowMutError {
  367. /// The value was dropped.
  368. Dropped(ValueDroppedError),
  369. /// The value was already borrowed.
  370. AlreadyBorrowed(AlreadyBorrowedError),
  371. /// The value was already borrowed mutably.
  372. AlreadyBorrowedMut(AlreadyBorrowedMutError),
  373. }
  374. impl Display for BorrowMutError {
  375. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  376. match self {
  377. BorrowMutError::Dropped(error) => Display::fmt(error, f),
  378. BorrowMutError::AlreadyBorrowedMut(error) => Display::fmt(error, f),
  379. BorrowMutError::AlreadyBorrowed(error) => Display::fmt(error, f),
  380. }
  381. }
  382. }
  383. impl Error for BorrowMutError {}
  384. /// An error that can occur when trying to use a value that has been dropped.
  385. #[derive(Debug, Copy, Clone)]
  386. pub struct ValueDroppedError {
  387. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  388. created_at: &'static std::panic::Location<'static>,
  389. }
  390. impl Display for ValueDroppedError {
  391. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  392. f.write_str("Failed to borrow because the value was dropped.")?;
  393. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  394. f.write_fmt(format_args!("created_at: {}", self.created_at))?;
  395. Ok(())
  396. }
  397. }
  398. impl std::error::Error for ValueDroppedError {}
  399. /// An error that can occur when trying to borrow a value that has already been borrowed mutably.
  400. #[derive(Debug, Copy, Clone)]
  401. pub struct AlreadyBorrowedMutError {
  402. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  403. borrowed_mut_at: &'static std::panic::Location<'static>,
  404. }
  405. impl Display for AlreadyBorrowedMutError {
  406. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  407. f.write_str("Failed to borrow because the value was already borrowed mutably.")?;
  408. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  409. f.write_fmt(format_args!("borrowed_mut_at: {}", self.borrowed_mut_at))?;
  410. Ok(())
  411. }
  412. }
  413. impl std::error::Error for AlreadyBorrowedMutError {}
  414. /// An error that can occur when trying to borrow a value mutably that has already been borrowed immutably.
  415. #[derive(Debug, Clone)]
  416. pub struct AlreadyBorrowedError {
  417. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  418. borrowed_at: Vec<&'static std::panic::Location<'static>>,
  419. }
  420. impl Display for AlreadyBorrowedError {
  421. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  422. f.write_str("Failed to borrow mutably because the value was already borrowed immutably.")?;
  423. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  424. f.write_str("borrowed_at:")?;
  425. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  426. for location in self.borrowed_at.iter() {
  427. f.write_fmt(format_args!("\t{}", location))?;
  428. }
  429. Ok(())
  430. }
  431. }
  432. impl std::error::Error for AlreadyBorrowedError {}
  433. /// A reference to a value in a generational box.
  434. pub struct GenerationalRef<T: 'static> {
  435. inner: Ref<'static, T>,
  436. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  437. borrow: GenerationalRefBorrowInfo,
  438. }
  439. impl<T: 'static> GenerationalRef<T> {
  440. /// Map one ref type to another.
  441. pub fn map<U, F>(orig: GenerationalRef<T>, f: F) -> GenerationalRef<U>
  442. where
  443. F: FnOnce(&T) -> &U,
  444. {
  445. GenerationalRef {
  446. inner: Ref::map(orig.inner, f),
  447. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  448. borrow: GenerationalRefBorrowInfo {
  449. borrowed_at: orig.borrow.borrowed_at,
  450. borrowed_from: orig.borrow.borrowed_from,
  451. },
  452. }
  453. }
  454. /// Filter one ref type to another.
  455. pub fn filter_map<U, F>(orig: GenerationalRef<T>, f: F) -> Option<GenerationalRef<U>>
  456. where
  457. F: FnOnce(&T) -> Option<&U>,
  458. {
  459. let Self {
  460. inner,
  461. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  462. borrow,
  463. } = orig;
  464. Ref::filter_map(inner, f).ok().map(|inner| GenerationalRef {
  465. inner,
  466. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  467. borrow: GenerationalRefBorrowInfo {
  468. borrowed_at: borrow.borrowed_at,
  469. borrowed_from: borrow.borrowed_from,
  470. },
  471. })
  472. }
  473. }
  474. impl<T: 'static> Deref for GenerationalRef<T> {
  475. type Target = T;
  476. fn deref(&self) -> &Self::Target {
  477. self.inner.deref()
  478. }
  479. }
  480. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  481. struct GenerationalRefBorrowInfo {
  482. borrowed_at: &'static std::panic::Location<'static>,
  483. borrowed_from: &'static MemoryLocationInner,
  484. }
  485. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  486. impl Drop for GenerationalRefBorrowInfo {
  487. fn drop(&mut self) {
  488. self.borrowed_from
  489. .borrowed_at
  490. .borrow_mut()
  491. .retain(|location| std::ptr::eq(*location, self.borrowed_at as *const _));
  492. }
  493. }
  494. /// A mutable reference to a value in a generational box.
  495. pub struct GenerationalRefMut<T: 'static> {
  496. inner: RefMut<'static, T>,
  497. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  498. borrow: GenerationalRefMutBorrowInfo,
  499. }
  500. impl<T: 'static> GenerationalRefMut<T> {
  501. /// Map one ref type to another.
  502. pub fn map<U, F>(orig: GenerationalRefMut<T>, f: F) -> GenerationalRefMut<U>
  503. where
  504. F: FnOnce(&mut T) -> &mut U,
  505. {
  506. GenerationalRefMut {
  507. inner: RefMut::map(orig.inner, f),
  508. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  509. borrow: orig.borrow,
  510. }
  511. }
  512. /// Filter one ref type to another.
  513. pub fn filter_map<U, F>(orig: GenerationalRefMut<T>, f: F) -> Option<GenerationalRefMut<U>>
  514. where
  515. F: FnOnce(&mut T) -> Option<&mut U>,
  516. {
  517. let Self {
  518. inner,
  519. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  520. borrow,
  521. } = orig;
  522. RefMut::filter_map(inner, f)
  523. .ok()
  524. .map(|inner| GenerationalRefMut {
  525. inner,
  526. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  527. borrow,
  528. })
  529. }
  530. }
  531. impl<T: 'static> Deref for GenerationalRefMut<T> {
  532. type Target = T;
  533. fn deref(&self) -> &Self::Target {
  534. self.inner.deref()
  535. }
  536. }
  537. impl<T: 'static> DerefMut for GenerationalRefMut<T> {
  538. fn deref_mut(&mut self) -> &mut Self::Target {
  539. self.inner.deref_mut()
  540. }
  541. }
  542. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  543. struct GenerationalRefMutBorrowInfo {
  544. borrowed_from: &'static MemoryLocationInner,
  545. }
  546. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  547. impl Drop for GenerationalRefMutBorrowInfo {
  548. fn drop(&mut self) {
  549. self.borrowed_from.borrowed_mut_at.take();
  550. }
  551. }
  552. /// Handles recycling generational boxes that have been dropped. Your application should have one store or one store per thread.
  553. #[derive(Clone)]
  554. pub struct Store {
  555. bump: &'static Bump,
  556. recycled: Rc<RefCell<Vec<MemoryLocation>>>,
  557. }
  558. impl Default for Store {
  559. fn default() -> Self {
  560. Self {
  561. bump: Box::leak(Box::new(Bump::new())),
  562. recycled: Default::default(),
  563. }
  564. }
  565. }
  566. impl Store {
  567. fn recycle(&self, location: MemoryLocation) {
  568. location.drop();
  569. self.recycled.borrow_mut().push(location);
  570. }
  571. fn claim(&self) -> MemoryLocation {
  572. if let Some(location) = self.recycled.borrow_mut().pop() {
  573. location
  574. } else {
  575. let data: &'static MemoryLocationInner = self.bump.alloc(MemoryLocationInner {
  576. data: RefCell::new(None),
  577. #[cfg(any(debug_assertions, feature = "check_generation"))]
  578. generation: Cell::new(0),
  579. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  580. borrowed_at: Default::default(),
  581. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  582. borrowed_mut_at: Default::default(),
  583. });
  584. MemoryLocation(data)
  585. }
  586. }
  587. /// Create a new owner. The owner will be responsible for dropping all of the generational boxes that it creates.
  588. pub fn owner(&self) -> Owner {
  589. Owner {
  590. store: self.clone(),
  591. owned: Default::default(),
  592. }
  593. }
  594. }
  595. /// Owner: Handles dropping generational boxes. The owner acts like a runtime lifetime guard. Any states that you create with an owner will be dropped when that owner is dropped.
  596. pub struct Owner {
  597. store: Store,
  598. owned: Rc<RefCell<Vec<MemoryLocation>>>,
  599. }
  600. impl Owner {
  601. /// Insert a value into the store. The value will be dropped when the owner is dropped.
  602. #[track_caller]
  603. pub fn insert<T: 'static>(&self, value: T) -> GenerationalBox<T> {
  604. let mut location = self.store.claim();
  605. let key = location.replace_with_caller(
  606. value,
  607. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  608. std::panic::Location::caller(),
  609. );
  610. self.owned.borrow_mut().push(location);
  611. key
  612. }
  613. /// Insert a value into the store with a specific location blamed for creating the value. The value will be dropped when the owner is dropped.
  614. pub fn insert_with_caller<T: 'static>(
  615. &self,
  616. value: T,
  617. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  618. caller: &'static std::panic::Location<'static>,
  619. ) -> GenerationalBox<T> {
  620. let mut location = self.store.claim();
  621. let key = location.replace_with_caller(
  622. value,
  623. #[cfg(any(debug_assertions, feature = "debug_borrows"))]
  624. caller,
  625. );
  626. self.owned.borrow_mut().push(location);
  627. key
  628. }
  629. /// Creates an invalid handle. This is useful for creating a handle that will be filled in later. If you use this before the value is filled in, you will get may get a panic or an out of date value.
  630. pub fn invalid<T: 'static>(&self) -> GenerationalBox<T> {
  631. let location = self.store.claim();
  632. let key = GenerationalBox {
  633. raw: location,
  634. #[cfg(any(debug_assertions, feature = "check_generation"))]
  635. generation: location.0.generation.get(),
  636. #[cfg(any(debug_assertions, feature = "debug_ownership"))]
  637. created_at: std::panic::Location::caller(),
  638. _marker: PhantomData,
  639. };
  640. self.owned.borrow_mut().push(location);
  641. key
  642. }
  643. }
  644. impl Drop for Owner {
  645. fn drop(&mut self) {
  646. for location in self.owned.borrow().iter() {
  647. self.store.recycle(*location)
  648. }
  649. }
  650. }