chiark / gitweb /
hidden: Fix handling of unnotched (Distinct) pieces
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 25 Apr 2022 00:01:20 +0000 (01:01 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 25 Apr 2022 00:31:17 +0000 (01:31 +0100)
We need to un-occult them.  But we were tracking what to recompute by
looking in occ.notches.  Un-notched pieces aren't there.

Introduce a new HashSet for these.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/hidden.rs
src/prelude.rs

index e2b02ec10f8344e1d437b0ce571da84657356a16..1dcdf43cbd177752b6d8e77319d14708fb64dcf8 100644 (file)
@@ -53,6 +53,7 @@ pub struct Occultation {
   region: Region, // automatically affect pieces here
   occulter: PieceId, // kept in synch with PieceOccult::active
   notches: Notches, // kept in synch with PieceOccult::passive
+  unnotched: HashSet<PieceId>, // kept in synch with PieceOccult::passive
   ppiece_use_size: Pos, // taken from first piece
   #[serde(flatten)] views: OccultationViews,
 }
@@ -145,7 +146,7 @@ impl PieceOccult {
                               -> Option<usize> {
     self.active_occ(goccults)?.map(|occ| {
       let notches_len = usize::try_from(occ.notches.len()).unwrap();
-      notches_len
+      notches_len + occ.unnotched.len()
     })
   }
 
@@ -159,6 +160,8 @@ impl PieceOccult {
         if let Some(notch) = permute_notch {
           occ.notches.remove(piece, notch)
             .unwrap_or_else(|e| error!("removing occulted piece {:?}", e));
+        } else {
+          occ.unnotched.remove(&piece);
         }
       }
     }
@@ -247,7 +250,10 @@ impl Occultation {
   }
 
   pub fn pieces(&self) -> impl Iterator<Item=PieceId> + '_ {
-    self.notches.iter()
+    chain!(
+      self.notches.iter(),
+      self.unnotched.iter().cloned(),
+    )
   }
 }
 
@@ -715,6 +721,10 @@ fn recalculate_occultation_general<
           .notches
           .remove(piece, old_notch)
           .unwrap();
+      } else {
+        occ
+          .unnotched
+          .remove(&piece);
       }
     };
     let passive = if_chain!{
@@ -724,7 +734,10 @@ fn recalculate_occultation_general<
       if let Some(ilk) = wants!( ipc.occilk.as_ref() );
       then {
         let permute_notch = match ilk {
-          IOI::Distinct(_) => None,
+          IOI::Distinct(_) => {
+            occ.unnotched.insert(piece);
+            None
+          },
           IOI::Mix(ilk) => {
             if_chain!{
               if occ.notches.is_empty();
@@ -983,6 +996,7 @@ pub fn create_occultation(
     views,
     ppiece_use_size: PosC::zero(),
     notches: default(),
+    unnotched: default(),
   };
   debug!("creating occultation {:?}", &occultation);
   trace_dbg!("recalc", &recalc);
index 5e700633b7bd0babb03f6d161be90ed92852f397..20c0f970a68930834cac8727108ad515db40a483 100644 (file)
@@ -73,7 +73,7 @@ pub use flexi_logger::LogSpecification;
 pub use fs2::FileExt;
 pub use if_chain::if_chain;
 pub use index_vec::{define_index_type, index_vec, IndexSlice, IndexVec};
-pub use itertools::{iproduct, izip, zip_eq, EitherOrBoth, Itertools};
+pub use itertools::{chain, iproduct, izip, zip_eq, EitherOrBoth, Itertools};
 pub use lazy_static::lazy_static;
 pub use log::{debug, error, info, trace, warn};
 pub use log::{log, log_enabled};