Skip to content

Commit a980afe

Browse files
committed
Flyweight: encapsulate tree colors into tree.rs
"Reg-green" pallette.
1 parent 397c772 commit a980afe

File tree

4 files changed

+20047
-20028
lines changed

4 files changed

+20047
-20028
lines changed

structural/flyweight/forest.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
mod tree;
22

3-
use draw::{Canvas, RGB};
3+
use draw::Canvas;
44
use std::{collections::HashMap, rc::Rc};
55
use tree::{Tree, TreeKind};
66

7+
pub use self::tree::TreeColor;
8+
79
#[derive(Default)]
810
pub struct Forest {
911
pub tree_kinds: HashMap<String, Rc<TreeKind>>,
1012
pub trees: Vec<Tree>,
1113
}
1214

1315
impl Forest {
14-
pub fn plant_tree(&mut self, x: u32, y: u32, name: String, color: RGB, data: String) {
15-
// Here is the "trick": there is always a single instance of a "tree kind" structure.
16+
pub fn plant_tree(&mut self, x: u32, y: u32, color: TreeColor, name: String, data: String) {
17+
// Here is the substance of the Flywheight Pattern:
18+
// there is always a single instance of a "tree kind" structure.
1619
let tree_kind = self
1720
.tree_kinds
1821
.entry(name.clone())
19-
.or_insert(Rc::new(TreeKind::new(name.clone(), color, data)));
22+
.or_insert(Rc::new(TreeKind::new(color, name.clone(), data)));
2023

2124
// A tree kind is referenced from each tree instance using `Rc` pointer.
2225
// `tree_kind.clone()` increases a reference counter instead of real cloning.
Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,69 @@
11
use std::rc::Rc;
22

3-
use draw::{Canvas, Color, Drawing, Shape, Style, RGB};
3+
use draw::{Canvas, Drawing, Shape, Style, RGB};
44

5-
pub struct Tree {
6-
x: u32,
7-
y: u32,
8-
kind: Rc<TreeKind>,
5+
pub enum TreeColor {
6+
Color1,
7+
Color2,
8+
TrunkColor,
99
}
1010

11-
impl Tree {
12-
pub fn new(x: u32, y: u32, kind: Rc<TreeKind>) -> Self {
13-
Self { x, y, kind }
14-
}
15-
16-
pub fn draw(&self, canvas: &mut Canvas) {
17-
self.kind.draw(canvas, self.x, self.y);
11+
impl TreeColor {
12+
fn rgb(&self) -> RGB {
13+
match self {
14+
Self::Color1 => RGB::new(0x17, 0xd7, 0xa0),
15+
Self::Color2 => RGB::new(0xd8, 0x21, 0x48),
16+
Self::TrunkColor => RGB::new(0x15, 0x1d, 0x3b),
17+
}
1818
}
1919
}
2020

2121
pub struct TreeKind {
22-
color: RGB,
22+
color: TreeColor,
2323
_name: String,
2424
_data: String,
2525
}
2626

2727
impl TreeKind {
28-
pub fn new(name: String, color: RGB, data: String) -> Self {
28+
pub fn new(color: TreeColor, _name: String, _data: String) -> Self {
2929
Self {
30-
_name: name,
3130
color,
32-
_data: data,
31+
_name,
32+
_data,
3333
}
3434
}
3535

3636
pub fn draw(&self, canvas: &mut Canvas, x: u32, y: u32) {
3737
let rect = Drawing::new()
38-
.with_xy(x.saturating_sub(1) as f32, y as f32)
38+
.with_xy(x.saturating_sub(2) as f32, y as f32)
3939
.with_shape(Shape::Rectangle {
40-
width: 2,
40+
width: 4,
4141
height: 5,
4242
})
43-
.with_style(Style::filled(Color::black()));
43+
.with_style(Style::filled(TreeColor::TrunkColor.rgb()));
4444

4545
let circle = Drawing::new()
4646
.with_xy(x as f32, y.saturating_sub(5) as f32)
4747
.with_shape(Shape::Circle { radius: 5 })
48-
.with_style(Style::filled(self.color));
48+
.with_style(Style::filled(self.color.rgb()));
4949

5050
canvas.display_list.add(rect);
5151
canvas.display_list.add(circle);
5252
}
5353
}
54+
55+
pub struct Tree {
56+
x: u32,
57+
y: u32,
58+
kind: Rc<TreeKind>,
59+
}
60+
61+
impl Tree {
62+
pub fn new(x: u32, y: u32, kind: Rc<TreeKind>) -> Self {
63+
Self { x, y, kind }
64+
}
65+
66+
pub fn draw(&self, canvas: &mut Canvas) {
67+
self.kind.draw(canvas, self.x, self.y);
68+
}
69+
}

structural/flyweight/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
mod forest;
22

3-
use draw::{render, render::svg::SvgRenderer, Canvas, RGB};
3+
use draw::{render, render::svg::SvgRenderer, Canvas};
44
use rand::Rng;
55

6-
use crate::forest::Forest;
6+
use crate::forest::{Forest, TreeColor};
77

88
const CANVAS_SIZE: u32 = 500;
99
const TREES_TO_DRAW: u32 = 100000;
@@ -18,16 +18,16 @@ fn main() {
1818
forest.plant_tree(
1919
rng.gen_range(0..CANVAS_SIZE),
2020
rng.gen_range(0..CANVAS_SIZE),
21+
TreeColor::Color1,
2122
"Summer Oak".into(),
22-
RGB::new(0, 0xff, 0), // Green
2323
"Oak texture stub".into(),
2424
);
2525

2626
forest.plant_tree(
2727
rng.gen_range(0..CANVAS_SIZE),
2828
rng.gen_range(0..CANVAS_SIZE),
29+
TreeColor::Color2,
2930
"Autumn Oak".into(),
30-
RGB::new(0xff, 0xa5, 0), // Orange
3131
"Autumn Oak texture stub".into(),
3232
);
3333
}

0 commit comments

Comments
 (0)