chiark / gitweb /
Introduce and use xdata_init
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 28 Apr 2022 00:15:01 +0000 (01:15 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 28 Apr 2022 00:15:01 +0000 (01:15 +0100)
Using get_mut for this seems slightly less careful.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/clock.rs
src/dice.rs
src/gamestate.rs

index 16fbfbdcb49d6a00f8e4c96ed8dbd9ef93e0687b..95eabb7fdfb5c691af541c692281ed5aec055222 100644 (file)
@@ -412,7 +412,7 @@ impl PieceSpec for Spec {
       spec: self.clone(),
     };
 
-    gpc.xdata_mut(|| State::new(self) )?;
+    gpc.xdata_init(State::new(self))?;
 
     SpecLoaded {
       p: Box::new(clock),
index 3f47b79ab071b400a7b4da9d7a1535299b121630..4b8b388af5799a058274ec82bf76877b68b3d9db 100644 (file)
@@ -174,7 +174,7 @@ impl PieceSpec for Spec {
     let initial_state = {
       State { cooldown_expires: cooldown_start_value(cooldown_time)? }
     };
-    let _state: &mut State = gpc.xdata_mut(|| initial_state)?;
+    gpc.xdata_init(initial_state)?;
 
     let occ_label = |occ: &OccultSpec| -> String {
       if occ.label == "" && labels.iter().any(|l| l != "") {
index 89123d9c3788a2eb8d8413de5471b643211711df..54045328370414f87fcac0fe0b734c9421ca377d 100644 (file)
@@ -457,6 +457,11 @@ impl GPiece {
     self.xdata.get_mut_exp()?
   }
 
+  #[throws(IE)]
+  pub fn xdata_init<T:PieceXData>(&mut self, val: T) -> &mut T {
+    self.xdata.init(val)?
+  }
+
   pub fn moveable(&self) -> PieceMoveable {
     if self.occult.is_active() { PieceMoveable::No }
     else { self.moveable }
@@ -500,6 +505,13 @@ fn xdata_unexpected<T:PieceXData>(got: &dyn PieceXData) -> InternalError {
     &got, T::dummy(),
   ))
 }
+fn xdata_unexpectedly_present(got: &dyn PieceXData) -> InternalError {
+  internal_logic_error(format!(
+    "\n\
+     piece xdata unexpectedly present: {:?}\n",
+    &got,
+  ))
+}
 fn xdata_missing<T:PieceXData>() -> InternalError {
   internal_logic_error(format!(
     "\n\
@@ -535,6 +547,16 @@ impl PieceXDataState {
     let xdata = self.as_mut().ok_or_else(|| xdata_missing::<T>())?;
     xdata_get_mut_inner(xdata)?
   }
+
+  #[throws(IE)]
+  fn init<T:PieceXData>(&mut self, val: T) -> &mut T {
+    if let Some(xdata) = self.as_ref() {
+      let xdata: &dyn PieceXData = &**xdata;
+      throw!(xdata_unexpectedly_present(xdata));
+    }
+    let xdata = self.insert(Box::new(val) as _);
+    xdata_get_mut_inner(xdata)?
+  }
 }
 
 fn xdata_get_mut_inner<