[lab2] Update pending compact applying

This commit is contained in:
Andrew Golovashevich 2026-02-15 23:30:55 +03:00
parent bab6598a0d
commit 178007edee
4 changed files with 89 additions and 40 deletions

View File

@ -1,3 +1,4 @@
use bgtu_ai_utility::{UpdatePending, UpdateTarget};
use std::cmp::min; use std::cmp::min;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::ops::{BitAnd, BitAndAssign, Index, IndexMut}; use std::ops::{BitAnd, BitAndAssign, Index, IndexMut};
@ -111,3 +112,21 @@ impl Debug for BitVector {
return Ok(()); return Ok(());
} }
} }
impl UpdateTarget for BitVector {
type Elem = bool;
fn add(&mut self, value: bool) {
let i = self.len();
*self = self.resized(i + 1);
self[i] = value
}
fn remove(&mut self, index: usize) {
let mut new = self.resized(self.len() - 1);
for j in index..new.len() {
new[j] = self[j + 1]
}
*self = new;
}
}

View File

@ -6,7 +6,7 @@ use crate::algo::BitVector;
use bgtu_ai_utility::gui::{boot_eframe, labeled_slider}; use bgtu_ai_utility::gui::{boot_eframe, labeled_slider};
use eframe::egui; use eframe::egui;
use egui_extras::{Column, TableBuilder}; use egui_extras::{Column, TableBuilder};
use bgtu_ai_utility::UpdatePending; use bgtu_ai_utility::{UpdatePending, UpdateTarget};
fn main() -> eframe::Result { fn main() -> eframe::Result {
return boot_eframe(|| MyApp::new()); return boot_eframe(|| MyApp::new());
@ -41,45 +41,15 @@ impl MyApp {
impl eframe::App for MyApp { impl eframe::App for MyApp {
fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) {
match self.columnUpdate { self.columnUpdate.apply_many_and_clear(
UpdatePending::NoChange => {} self.data.iter_mut(),
UpdatePending::Add => { || false
self.data = self );
.data
.iter()
.map(|oldVec| oldVec.resized(oldVec.len() + 1))
.collect();
self.bitCount += 1;
self.columnUpdate = UpdatePending::NoChange;
}
UpdatePending::Remove(i) => {
self.data = self
.data
.iter()
.map(|oldVec| {
let mut newVec = oldVec.resized(oldVec.len() - 1);
for j in i..newVec.len() {
newVec[j] = oldVec[j + 1]
}
return newVec;
})
.collect();
self.bitCount -= 1; self.rowUpdate.apply_and_clear(
self.columnUpdate = UpdatePending::NoChange; &mut self.data,
} || BitVector::alloc(self.bitCount)
} );
match self.rowUpdate {
UpdatePending::NoChange => {}
UpdatePending::Add => {
self.data.push(BitVector::alloc(self.bitCount));
self.rowUpdate = UpdatePending::NoChange;
}
UpdatePending::Remove(i) => {
self.data.remove(i);
self.rowUpdate = UpdatePending::NoChange;
}
}
egui::CentralPanel::default().show(ui, |ui| { egui::CentralPanel::default().show(ui, |ui| {
ui.add_enabled_ui(matches!(self.result, None), |ui| { ui.add_enabled_ui(matches!(self.result, None), |ui| {

View File

@ -2,4 +2,4 @@ pub mod graph;
pub mod gui; pub mod gui;
mod update_pending; mod update_pending;
pub use update_pending::UpdatePending; pub use update_pending::{UpdatePending, UpdateTarget};

View File

@ -2,4 +2,64 @@ pub enum UpdatePending {
NoChange, NoChange,
Add, Add,
Remove(usize), Remove(usize),
}
impl UpdatePending {
pub fn apply<C: UpdateTarget>(&self, target: &mut C, constructor: impl FnOnce() -> C::Elem) {
match self {
UpdatePending::NoChange => {}
UpdatePending::Add => target.add(constructor()),
UpdatePending::Remove(i) => target.remove(*i),
}
}
pub fn apply_and_clear<C: UpdateTarget>(
&mut self,
target: &mut C,
constructor: impl FnOnce() -> C::Elem,
) {
match self {
UpdatePending::NoChange => return,
UpdatePending::Add => target.add(constructor()),
UpdatePending::Remove(i) => target.remove(*i),
}
*self = UpdatePending::NoChange;
}
pub fn apply_many<'c, C: UpdateTarget + 'c>(
&self,
it: impl Iterator<Item = &'c mut C>,
constructor: impl Fn() -> C::Elem,
) {
for e in it {
self.apply(e, || constructor())
}
}
pub fn apply_many_and_clear<'c, C: UpdateTarget + 'c>(
&mut self,
it: impl Iterator<Item = &'c mut C>,
constructor: impl Fn() -> C::Elem,
) {
self.apply_many(it, constructor);
*self = UpdatePending::NoChange;
}
}
pub trait UpdateTarget {
type Elem;
fn add(&mut self, value: Self::Elem);
fn remove(&mut self, index: usize);
}
impl <T> UpdateTarget for Vec<T> {
type Elem = T;
fn add(&mut self, value: Self::Elem) {
self.push(value);
}
fn remove(&mut self, index: usize) {
Vec::remove(self, index);
}
} }