egui
This commit is contained in:
parent
a808e7996b
commit
bff268515d
5 changed files with 1311 additions and 1673 deletions
2807
Cargo.lock
generated
2807
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
ctx.request_repaint();
|
||||||
|
for _ in 0..100 {
|
||||||
|
self.dish.fire_blindly();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn paint_chunk(painter: Painter, chunk: &Chunk) {
|
||||||
|
let bounds = painter.clip_rect();
|
||||||
|
let size = 16.;
|
||||||
for x in 0..CHUNK_SIZE {
|
for x in 0..CHUNK_SIZE {
|
||||||
render_pixel_pair(dish, x, y);
|
for y in 0..CHUNK_SIZE {
|
||||||
|
let cell = &chunk.get_cell(x, y);
|
||||||
|
let corner = bounds.min + (Vec2::from((x as f32, y as f32)) * size);
|
||||||
|
let rect = Rect::from_min_size(corner, Vec2::splat(size));
|
||||||
|
let color = Color32::from_rgb(cell.0, cell.1, cell.2);
|
||||||
|
painter.rect(rect, 0., color, (1., Color32::GRAY));
|
||||||
}
|
}
|
||||||
println!();
|
|
||||||
}
|
}
|
||||||
println!();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_pixel_pair(dish: &Dish, x: usize, y: usize) {
|
fn rule_editor(ui: &mut Ui, rule: &mut Rule) {
|
||||||
let a = dish.get_cell(x, y * 2) != Some(Cell::EMPTY);
|
let patt_height = rule.from.height();
|
||||||
let b = dish.get_cell(x, y * 2 + 1) != Some(Cell::EMPTY);
|
let patt_width = rule.from.height();
|
||||||
let char = match (a, b) {
|
|
||||||
(false, false) => " ",
|
|
||||||
(false, true) => "▄",
|
|
||||||
(true, false) => "▀",
|
|
||||||
(true, true) => "█",
|
|
||||||
};
|
|
||||||
print!("{}", char.fg_rgb::<255, 147, 219>());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wait_for_input() {
|
const CSIZE: f32 = 24.;
|
||||||
std::io::stdin().read_line(&mut String::new()).unwrap();
|
|
||||||
|
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),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue