1use crate::{Link, LinkType};
2use mcai_types::Coordinates;
3use std::{cell::RefCell, rc::Rc};
4
5pub type SharedNode = Rc<RefCell<Node>>;
6
7#[derive(Clone, Debug, PartialEq)]
8pub struct Dimensions {
9 width: usize,
10 height: usize,
11}
12
13impl Dimensions {
14 pub fn new(width: usize, height: usize) -> Self {
15 Self { width, height }
16 }
17
18 pub fn width(&self) -> usize {
19 self.width
20 }
21
22 pub fn height(&self) -> usize {
23 self.height
24 }
25}
26
27#[derive(Clone, Debug, PartialEq)]
28pub struct Node {
29 id: u32,
30 coordinates: Coordinates,
31 dimensions: Dimensions,
32 parents: Vec<SharedNode>,
33 requires: Vec<SharedNode>,
34}
35
36impl Node {
37 pub fn new(id: u32, coordinates: Coordinates, dimensions: Dimensions) -> Self {
38 Node {
39 id,
40 coordinates,
41 dimensions,
42 parents: vec![],
43 requires: vec![],
44 }
45 }
46
47 pub fn into_rc(self) -> SharedNode {
48 Rc::new(RefCell::new(self))
49 }
50
51 pub fn id(&self) -> u32 {
52 self.id
53 }
54
55 pub fn coordinates(&self) -> Coordinates {
56 self.coordinates.clone()
57 }
58
59 pub fn dimensions(&self) -> Dimensions {
60 self.dimensions.clone()
61 }
62
63 pub fn parents(&self) -> Vec<SharedNode> {
64 self.parents.clone()
65 }
66
67 pub fn required(&self) -> Vec<SharedNode> {
68 self.requires.clone()
69 }
70
71 pub fn get_input_coordinates(&self) -> Coordinates {
72 let mut coordinates = self.coordinates.clone();
73 coordinates.x += (self.dimensions.width / 2) as isize;
74 coordinates
75 }
76
77 pub fn get_output_coordinates(&self) -> Coordinates {
78 let mut coordinates = self.coordinates.clone();
79 coordinates.x += (self.dimensions.width / 2) as isize;
80 coordinates.y += (self.dimensions.height) as isize;
81 coordinates
82 }
83
84 pub fn get_links(&self, link_type: &LinkType) -> Vec<Link> {
85 match link_type {
86 LinkType::Parentage => &self.parents,
87 LinkType::Requirement => &self.requires,
88 }
89 .iter()
90 .map(|node| (self, node.borrow(), *link_type))
91 .map(Link::from)
92 .collect::<Vec<Link>>()
93 }
94
95 pub fn set_parents(&mut self, parents: Vec<SharedNode>) {
96 self.parents = parents;
97 }
98
99 pub fn set_required_nodes(&mut self, required_to_start: Vec<SharedNode>) {
100 self.requires = required_to_start;
101 }
102
103 pub fn set_coordinates(&mut self, coordinates: Coordinates) {
104 self.coordinates = coordinates;
105 }
106
107 pub fn add_parent(&mut self, parent: SharedNode) {
108 if !self.parents.contains(&parent) {
109 self.parents.push(parent);
110 }
111 }
112
113 pub fn add_required(&mut self, required: SharedNode) {
114 if !self.requires.contains(&required) {
115 self.requires.push(required);
116 }
117 }
118
119 pub fn remove_parent(&mut self, parent_id: u32) {
120 self
121 .parents
122 .retain(|parent| parent.borrow().id != parent_id);
123 }
124
125 pub fn remove_required(&mut self, required_id: u32) {
126 self
127 .requires
128 .retain(|required| required.borrow().id != required_id);
129 }
130}