This commit is contained in:
Crispy 2024-04-30 23:24:45 +02:00
parent a808e7996b
commit bff268515d
5 changed files with 1311 additions and 1673 deletions

2807
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,3 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = ["petri", "uscope"] members = ["petri", "uscope"]
# Enable a small amount of optimization in debug mode
[profile.dev]
opt-level = 1
# Enable high optimizations for dependencies (incl. Bevy), but not for our code:
[profile.dev.package."*"]
opt-level = 3

View file

@ -3,7 +3,7 @@ use rand::prelude::*;
pub const CHUNK_SIZE: usize = 32; pub const CHUNK_SIZE: usize = 32;
#[derive(Debug, Default, PartialEq, Clone)] #[derive(Debug, Default, PartialEq, Clone)]
pub struct Cell(u8, u8, u8); pub struct Cell(pub u8, pub u8, pub u8);
#[derive(Debug)] #[derive(Debug)]
pub struct Pos2(i8, i8); pub struct Pos2(i8, i8);
@ -42,14 +42,14 @@ impl Chunk {
for col in self.contents.iter_mut() { for col in self.contents.iter_mut() {
for cell in col.iter_mut() { for cell in col.iter_mut() {
if random::<u8>() % 4 == 0 { if random::<u8>() % 4 == 0 {
*cell = Cell::WHITE; *cell = Cell::PINK;
} }
} }
} }
self self
} }
fn get_cell(&self, x: usize, y: usize) -> Cell { pub fn get_cell(&self, x: usize, y: usize) -> Cell {
self.contents[x][y].clone() self.contents[x][y].clone()
} }
@ -67,56 +67,36 @@ impl Dish {
from: RulePattern { from: RulePattern {
width: 1, width: 1,
height: 2, height: 2,
contents: vec![Some(Cell::WHITE), Some(Cell::EMPTY)], contents: vec![Some(Cell::PINK), Some(Cell::EMPTY)],
}, },
to: RulePattern { to: RulePattern {
width: 1, width: 1,
height: 2, height: 2,
contents: vec![Some(Cell::EMPTY), Some(Cell::WHITE)], contents: vec![Some(Cell::EMPTY), Some(Cell::PINK)],
}, },
}, },
Rule { Rule {
from: RulePattern { from: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
contents: vec![ contents: vec![Some(Cell::PINK), None, Some(Cell::PINK), Some(Cell::EMPTY)],
Some(Cell::WHITE),
None,
Some(Cell::WHITE),
Some(Cell::EMPTY),
],
}, },
to: RulePattern { to: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
contents: vec![ contents: vec![Some(Cell::EMPTY), None, Some(Cell::PINK), Some(Cell::PINK)],
Some(Cell::EMPTY),
None,
Some(Cell::WHITE),
Some(Cell::WHITE),
],
}, },
}, },
Rule { Rule {
from: RulePattern { from: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
contents: vec![ contents: vec![None, Some(Cell::PINK), Some(Cell::EMPTY), Some(Cell::PINK)],
None,
Some(Cell::WHITE),
Some(Cell::EMPTY),
Some(Cell::WHITE),
],
}, },
to: RulePattern { to: RulePattern {
width: 2, width: 2,
height: 2, height: 2,
contents: vec![ contents: vec![None, Some(Cell::EMPTY), Some(Cell::PINK), Some(Cell::PINK)],
None,
Some(Cell::EMPTY),
Some(Cell::WHITE),
Some(Cell::WHITE),
],
}, },
}, },
], ],
@ -181,6 +161,7 @@ impl Dish {
impl Cell { impl Cell {
pub const EMPTY: Self = Self(0, 0, 0); pub const EMPTY: Self = Self(0, 0, 0);
pub const WHITE: Self = Self(255, 255, 255); pub const WHITE: Self = Self(255, 255, 255);
pub const PINK: Self = Self(255, 147, 219);
} }
#[derive(Debug)] #[derive(Debug)]
@ -191,11 +172,19 @@ pub struct RulePattern {
} }
impl RulePattern { impl RulePattern {
fn get(&self, x: usize, y: usize) -> Option<Cell> { pub fn get(&self, x: usize, y: usize) -> Option<Cell> {
if x >= self.width || y >= self.height { if x >= self.width || y >= self.height {
None None
} else { } else {
self.contents[x + self.width * y].clone() self.contents[x + self.width * y].clone()
} }
} }
pub fn height(&self) -> usize {
self.height
}
pub fn width(&self) -> usize {
self.width
}
} }

View file

@ -7,5 +7,4 @@ edition = "2021"
[dependencies] [dependencies]
petri = { path = "../petri" } petri = { path = "../petri" }
bevy = { version = "0.13", features = ["dynamic_linking"] } eframe = "0.27.2"
owo-colors = "4.0.0"

View file

@ -1,39 +1,102 @@
use owo_colors::OwoColorize; use eframe::{
use petri::{Cell, Dish, CHUNK_SIZE}; egui::{CentralPanel, Color32, Painter, Rect, SidePanel, Ui, Vec2},
NativeOptions,
};
use petri::{Chunk, Dish, Rule, CHUNK_SIZE};
fn main() { fn main() {
let mut dish = Dish::new(); eframe::run_native(
loop { "V3 World Editor",
for _ in 0..1000 { NativeOptions::default(),
dish.fire_blindly(); Box::new(|_cc| Box::new(UScope::new(_cc))),
} )
print_dish(&dish); .unwrap();
wait_for_input() }
#[derive(Debug)]
struct UScope {
dish: Dish,
}
impl UScope {
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
Self { dish: Dish::new() }
} }
} }
fn print_dish(dish: &Dish) { impl eframe::App for UScope {
for y in 0..(CHUNK_SIZE / 2) { fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
for x in 0..CHUNK_SIZE { ctx.request_repaint();
render_pixel_pair(dish, x, y); for _ in 0..100 {
self.dish.fire_blindly();
} }
println!(); SidePanel::left("left_panel").show(ctx, |ui| {
ui.heading("Rules");
ui.text_edit_singleline(&mut "dummy");
if ui.button("aaa").clicked() {
dbg!(&self.dish.rules);
}
for rule in &mut self.dish.rules {
rule_editor(ui, rule);
}
});
CentralPanel::default().show(ctx, |ui| {
let bounds = ui.available_rect_before_wrap();
let painter = ui.painter_at(bounds);
paint_chunk(painter, &self.dish.chunk);
});
} }
println!();
} }
fn render_pixel_pair(dish: &Dish, x: usize, y: usize) { fn paint_chunk(painter: Painter, chunk: &Chunk) {
let a = dish.get_cell(x, y * 2) != Some(Cell::EMPTY); let bounds = painter.clip_rect();
let b = dish.get_cell(x, y * 2 + 1) != Some(Cell::EMPTY); let size = 16.;
let char = match (a, b) { for x in 0..CHUNK_SIZE {
(false, false) => " ", for y in 0..CHUNK_SIZE {
(false, true) => "", let cell = &chunk.get_cell(x, y);
(true, false) => "", let corner = bounds.min + (Vec2::from((x as f32, y as f32)) * size);
(true, true) => "", let rect = Rect::from_min_size(corner, Vec2::splat(size));
}; let color = Color32::from_rgb(cell.0, cell.1, cell.2);
print!("{}", char.fg_rgb::<255, 147, 219>()); painter.rect(rect, 0., color, (1., Color32::GRAY));
}
}
} }
pub fn wait_for_input() { fn rule_editor(ui: &mut Ui, rule: &mut Rule) {
std::io::stdin().read_line(&mut String::new()).unwrap(); let patt_height = rule.from.height();
let patt_width = rule.from.height();
const CSIZE: f32 = 24.;
let (_, bounds) = ui.allocate_space(Vec2::new(
CSIZE * (patt_width * 2 + 1) as f32,
CSIZE * patt_height as f32,
));
for x in 0..patt_width {
for y in 0..patt_height {
let rect = Rect::from_min_size(
bounds.min + Vec2::from((x as f32, y as f32)) * CSIZE,
Vec2::splat(CSIZE),
);
if let Some(cell) = rule.from.get(x, y) {
ui.painter().rect(
rect,
2.,
Color32::from_rgb(cell.0, cell.1, cell.2),
(1., Color32::GRAY),
);
}
if let Some(cell) = rule.to.get(x, y) {
let rect = rect.translate(Vec2::X * (patt_width as f32 + 1.) * CSIZE);
ui.painter().rect(
rect,
2.,
Color32::from_rgb(cell.0, cell.1, cell.2),
(1., Color32::GRAY),
);
}
}
}
} }