Adapt the app to the new slab tree

This commit is contained in:
Savanni D'Gerinel 2024-04-30 20:31:17 -04:00
parent b1374229f3
commit 5441a3c441
5 changed files with 25 additions and 25 deletions

View File

@ -29,5 +29,6 @@ pub mod library;
pub mod settings; pub mod settings;
mod types; mod types;
pub use types::{BoardError, Color, Config, ConfigOption, LibraryPath, Player, Rank, Size}; pub use types::{
BoardError, Color, Config, ConfigOption, DepthTree, LibraryPath, Player, Rank, Size,
};

View File

@ -242,7 +242,7 @@ pub struct Tree<T> {
} }
*/ */
struct DepthTree(slab_tree::Tree<SizeNode>); pub struct DepthTree(slab_tree::Tree<SizeNode>);
impl Deref for DepthTree { impl Deref for DepthTree {
type Target = slab_tree::Tree<SizeNode>; type Target = slab_tree::Tree<SizeNode>;
@ -393,13 +393,13 @@ impl DepthTree {
width width
} }
*/
pub fn bfs_iter(&self) -> BFSIter<T> { pub fn bfs_iter(&self) -> BFSIter<'_, SizeNode> {
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
queue.push_back(&self.nodes[0]); queue.push_back(self.0.root().unwrap());
BFSIter { tree: self, queue } BFSIter { tree: self, queue }
} }
*/
} }
impl<'a> From<&'a GameTree> for DepthTree { impl<'a> From<&'a GameTree> for DepthTree {
@ -520,27 +520,24 @@ impl<'a> From<&'a GameNode> for Tree<Uuid> {
} }
*/ */
/*
pub struct BFSIter<'a, T> { pub struct BFSIter<'a, T> {
tree: &'a Tree<T>, tree: &'a DepthTree,
queue: VecDeque<&'a Node<T>>, queue: VecDeque<slab_tree::NodeRef<'a, T>>,
} }
impl<'a, T> Iterator for BFSIter<'a, T> { impl<'a, T> Iterator for BFSIter<'a, T> {
type Item = &'a Node<T>; type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let retval = self.queue.pop_front(); let retval = self.queue.pop_front();
if let Some(retval) = retval { if let Some(ref retval) = retval {
retval retval
.children .children()
.iter() .for_each(|noderef| self.queue.push_back(noderef));
.for_each(|idx| self.queue.push_back(&self.tree.nodes[*idx]));
} }
retval retval.map(|retval| retval.data())
} }
} }
*/
#[cfg(test)] #[cfg(test)]
mod test { mod test {

View File

@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with On
use cairo::Context; use cairo::Context;
use glib::Object; use glib::Object;
use gtk::{prelude::*, subclass::prelude::*}; use gtk::{prelude::*, subclass::prelude::*};
use otg_core::Tree; use otg_core::DepthTree;
use sgf::GameRecord; use sgf::GameRecord;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use uuid::Uuid; use uuid::Uuid;
@ -28,7 +28,7 @@ const HEIGHT: i32 = 800;
#[derive(Default)] #[derive(Default)]
pub struct ReviewTreePrivate { pub struct ReviewTreePrivate {
record: Rc<RefCell<Option<GameRecord>>>, record: Rc<RefCell<Option<GameRecord>>>,
tree: Rc<RefCell<Option<Tree<Uuid>>>>, tree: Rc<RefCell<Option<DepthTree>>>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -50,7 +50,9 @@ impl ReviewTree {
pub fn new(record: GameRecord) -> Self { pub fn new(record: GameRecord) -> Self {
let s: Self = Object::new(); let s: Self = Object::new();
*s.imp().tree.borrow_mut() = Some(Tree::from(&record.children[0])); // TODO: there can be more than one tree, especially in instructional files. Either unify
// them into a single tree in the GameTree, or draw all of them here.
*s.imp().tree.borrow_mut() = Some(DepthTree::from(&record.trees[0]));
*s.imp().record.borrow_mut() = Some(record); *s.imp().record.borrow_mut() = Some(record);
s.set_width_request(WIDTH); s.set_width_request(WIDTH);
@ -67,7 +69,7 @@ impl ReviewTree {
} }
pub fn redraw(&self, ctx: &Context, _width: i32, _height: i32) { pub fn redraw(&self, ctx: &Context, _width: i32, _height: i32) {
let tree: &Option<Tree<Uuid>> = &self.imp().tree.borrow(); let tree: &Option<DepthTree> = &self.imp().tree.borrow();
match tree { match tree {
Some(ref tree) => { Some(ref tree) => {
for node in tree.bfs_iter() { for node in tree.bfs_iter() {
@ -76,7 +78,7 @@ impl ReviewTree {
// the parent? do I need to just make it more intrinsically a part of the position // the parent? do I need to just make it more intrinsically a part of the position
// code? // code?
ctx.set_source_rgb(0.7, 0.7, 0.7); ctx.set_source_rgb(0.7, 0.7, 0.7);
let (row, column) = tree.position(node.id); let (row, column) = node.position();
let y = (row as f64) * 20. + 10.; let y = (row as f64) * 20. + 10.;
let x = (column as f64) * 20. + 10.; let x = (column as f64) * 20. + 10.;
ctx.arc(x, y, 5., 0., 2. * std::f64::consts::PI); ctx.arc(x, y, 5., 0., 2. * std::f64::consts::PI);

View File

@ -55,9 +55,10 @@ impl GameReview {
// It's actually really bad to be just throwing away errors. Panics make everyone unhappy. // It's actually really bad to be just throwing away errors. Panics make everyone unhappy.
// This is not a fatal error, so I'll replace this `unwrap` call with something that // This is not a fatal error, so I'll replace this `unwrap` call with something that
// renders the board and notifies the user of a problem that cannot be resolved. // renders the board and notifies the user of a problem that cannot be resolved.
let board_repr = otg_core::Goban::default() let board_repr = match record.mainline() {
.apply_moves(record.mainline()) Some(iter) => otg_core::Goban::default().apply_moves(iter).unwrap(),
.unwrap(); None => otg_core::Goban::default(),
};
let board = Goban::new(board_repr, resources); let board = Goban::new(board_repr, resources);
/* /*

View File

@ -136,7 +136,6 @@ impl GameRecord {
/// was actually played out, and by convention consists of the first node in each list of /// was actually played out, and by convention consists of the first node in each list of
/// children. /// children.
pub fn mainline(&self) -> Option<impl Iterator<Item = &'_ GameNode>> { pub fn mainline(&self) -> Option<impl Iterator<Item = &'_ GameNode>> {
println!("number of trees: {}", self.trees.len());
if !self.trees.is_empty() { if !self.trees.is_empty() {
Some(MainlineIter { Some(MainlineIter {
next: self.trees[0].root(), next: self.trees[0].root(),