bumpframe.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use crate::innerlude::*;
  2. use bumpalo::Bump;
  3. use std::cell::Cell;
  4. pub(crate) struct ActiveFrame {
  5. pub cur_generation: Cell<usize>,
  6. // The double-buffering situation that we will use
  7. pub frames: [BumpFrame; 2],
  8. }
  9. impl ActiveFrame {
  10. pub fn new() -> Self {
  11. let b1 = Bump::new();
  12. let b2 = Bump::new();
  13. let frame_a = BumpFrame {
  14. bump: b1,
  15. generation: 0.into(),
  16. };
  17. let frame_b = BumpFrame {
  18. bump: b2,
  19. generation: 0.into(),
  20. };
  21. Self {
  22. frames: [frame_a, frame_b],
  23. cur_generation: 0.into(),
  24. }
  25. }
  26. pub unsafe fn reset_wip_frame(&self) {
  27. // todo: unsafecell or something
  28. let bump = self.wip_frame() as *const _ as *mut BumpFrame;
  29. let g = &mut *bump;
  30. g.bump.reset();
  31. // self.wip_frame_mut().bump.reset()
  32. }
  33. /// The "work in progress frame" represents the frame that is currently being worked on.
  34. pub fn wip_frame(&self) -> &BumpFrame {
  35. match self.cur_generation.get() & 1 == 0 {
  36. true => &self.frames[0],
  37. false => &self.frames[1],
  38. }
  39. }
  40. pub fn wip_frame_mut(&mut self) -> &mut BumpFrame {
  41. match self.cur_generation.get() & 1 == 0 {
  42. true => &mut self.frames[0],
  43. false => &mut self.frames[1],
  44. }
  45. }
  46. /// The finished frame represents the frame that has been "finished" and cannot be modified again
  47. pub fn finished_frame(&self) -> &BumpFrame {
  48. match self.cur_generation.get() & 1 == 1 {
  49. true => &self.frames[0],
  50. false => &self.frames[1],
  51. }
  52. }
  53. // /// Give out our self-referential item with our own borrowed lifetime
  54. // pub fn fin_head<'b>(&'b self) -> &'b VNode<'b> {
  55. // let cur_head = &self.finished_frame().head_node;
  56. // unsafe { std::mem::transmute::<&VNode<'static>, &VNode<'b>>(cur_head) }
  57. // }
  58. // /// Give out our self-referential item with our own borrowed lifetime
  59. // pub fn wip_head<'b>(&'b self) -> &'b VNode<'b> {
  60. // let cur_head = &self.wip_frame().head_node;
  61. // unsafe { std::mem::transmute::<&VNode<'static>, &VNode<'b>>(cur_head) }
  62. // }
  63. pub fn cycle_frame(&mut self) {
  64. self.cur_generation.set(self.cur_generation.get() + 1);
  65. }
  66. }
  67. #[cfg(test)]
  68. mod tests {
  69. //! These tests are bad. I don't have a good way of properly testing the ActiveFrame stuff
  70. use super::*;
  71. #[test]
  72. fn test_bump_frame() {
  73. let mut frames = ActiveFrame::new();
  74. // just cycle a few times and make sure we get the right frames out
  75. for _ in 0..5 {
  76. let fin = frames.finished_frame();
  77. let wip = frames.wip_frame();
  78. assert_eq!(wip._name, "wip");
  79. assert_eq!(fin._name, "fin");
  80. frames.cycle_frame();
  81. let fin = frames.finished_frame();
  82. let wip = frames.wip_frame();
  83. assert_eq!(wip._name, "fin");
  84. assert_eq!(fin._name, "wip");
  85. frames.cycle_frame();
  86. }
  87. assert_eq!(frames.cur_generation.get(), 10);
  88. }
  89. }