Game tree becomes a tree of UUIDs, not GameNodes

Doing this avoids reference lifetime hell
This commit is contained in:
Savanni D'Gerinel 2024-03-30 11:00:54 -04:00
parent b481d5d058
commit 9fbc630500
5 changed files with 25 additions and 17 deletions

2
Cargo.lock generated
View File

@ -2709,6 +2709,7 @@ dependencies = [
"serde_json", "serde_json",
"sgf", "sgf",
"thiserror", "thiserror",
"uuid 0.8.2",
] ]
[[package]] [[package]]
@ -2728,6 +2729,7 @@ dependencies = [
"pango", "pango",
"sgf", "sgf",
"tokio", "tokio",
"uuid 0.8.2",
] ]
[[package]] [[package]]

View File

@ -15,6 +15,7 @@ grid = { version = "0.9" }
serde_json = { version = "1" } serde_json = { version = "1" }
serde = { version = "1", features = [ "derive" ] } serde = { version = "1", features = [ "derive" ] }
thiserror = { version = "1" } thiserror = { version = "1" }
uuid = { version = "0.8", features = ["v4", "serde"] }
[dev-dependencies] [dev-dependencies]
cool_asserts = { version = "2" } cool_asserts = { version = "2" }

View File

@ -3,6 +3,7 @@ use config::define_config;
use config_derive::ConfigOption; use config_derive::ConfigOption;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sgf::GameNode; use sgf::GameNode;
use uuid::Uuid;
use std::{cell::RefCell, fmt, path::PathBuf, time::Duration}; use std::{cell::RefCell, fmt, path::PathBuf, time::Duration};
use thiserror::Error; use thiserror::Error;
@ -334,10 +335,10 @@ impl<T> Tree<T> {
} }
} }
impl<'a> From<&'a GameNode> for Tree<&'a GameNode> { impl<'a> From<&'a GameNode> for Tree<Uuid> {
fn from(root: &'a GameNode) -> Self { fn from(root: &'a GameNode) -> Self {
fn add_subtree<'a>(tree: &mut Tree<&'a GameNode>, parent_idx: usize, node: &'a GameNode) { fn add_subtree<'a>(tree: &mut Tree<Uuid>, parent_idx: usize, node: &'a GameNode) {
let idx = tree.add_node(parent_idx, node); let idx = tree.add_node(parent_idx, node.id());
let children = match node { let children = match node {
GameNode::MoveNode(node) => &node.children, GameNode::MoveNode(node) => &node.children,
@ -349,7 +350,7 @@ impl<'a> From<&'a GameNode> for Tree<&'a GameNode> {
} }
} }
let mut tree = Tree::new(root); let mut tree = Tree::new(root.id());
let children = match root { let children = match root {
GameNode::MoveNode(node) => &node.children, GameNode::MoveNode(node) => &node.children,

View File

@ -21,6 +21,7 @@ otg-core = { path = "../core" }
pango = { version = "*" } pango = { version = "*" }
sgf = { path = "../../sgf" } sgf = { path = "../../sgf" }
tokio = { version = "1.26", features = [ "full" ] } tokio = { version = "1.26", features = [ "full" ] }
uuid = { version = "0.8", features = ["v4", "serde"] }
[build-dependencies] [build-dependencies]
glib-build-tools = "0.17" glib-build-tools = "0.17"

View File

@ -17,14 +17,18 @@ 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 sgf::{GameNode, GameRecord}; use sgf::{GameNode, GameRecord};
use std::{cell::RefCell, rc::Rc};
use uuid::Uuid;
const WIDTH: i32 = 200; const WIDTH: i32 = 200;
const HEIGHT: i32 = 800; 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>>>>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -43,9 +47,12 @@ glib::wrapper! {
} }
impl ReviewTree { 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]));
*s.imp().record.borrow_mut() = Some(record);
s.set_width_request(WIDTH); s.set_width_request(WIDTH);
s.set_height_request(HEIGHT); s.set_height_request(HEIGHT);
@ -124,7 +131,9 @@ fn node_width(node: &GameNode) -> usize {
} }
// If there is more than one child, run node_width on each one and add them together. // If there is more than one child, run node_width on each one and add them together.
children.iter().fold(0, |acc, child| acc + node_width(child)) children
.iter()
.fold(0, |acc, child| acc + node_width(child))
} }
// Since I know the width of a node, now I want to figure out its placement in the larger scheme of // Since I know the width of a node, now I want to figure out its placement in the larger scheme of
@ -137,14 +146,6 @@ fn node_width(node: &GameNode) -> usize {
// //
// Just having the node is greatly insufficient. I can get better results if I'm calculating the // Just having the node is greatly insufficient. I can get better results if I'm calculating the
// position of its children. // position of its children.
#[allow(dead_code)]
fn node_children_columns(_node: &GameNode) -> Vec<usize> {
vec![0, 1, 2]
}
#[allow(dead_code)]
fn print_node_tree(node: &GameNode) {
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -237,12 +238,14 @@ mod test {
node_a.children.push(node_c.clone()); node_a.children.push(node_c.clone());
node_a.children.push(node_d.clone()); node_a.children.push(node_d.clone());
assert_eq!(node_children_columns(&GameNode::MoveNode(node_a)), vec![0, 1, 2]); assert_eq!(
node_children_columns(&GameNode::MoveNode(node_a)),
vec![0, 1, 2]
);
} }
#[test] #[test]
fn text_renderer() { fn text_renderer() {
assert!(false); assert!(false);
} }
} }