add tracing support
This commit is contained in:
parent
a70db904f5
commit
4eccbf78e0
217
Cargo.lock
generated
217
Cargo.lock
generated
@ -165,15 +165,6 @@ version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
@ -233,8 +224,6 @@ dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"nalgebra",
|
||||
"ndarray",
|
||||
"ndarray-linalg",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
@ -678,27 +667,6 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cauchy"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ff11ddd2af3b5e80dd0297fee6e56ac038d9bdc549573cdb51bd6d2efe7f05e"
|
||||
dependencies = [
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cblas-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6feecd82cce51b0204cf063f0041d69f24ce83f680d87514b004248e7b0fa65"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
@ -1597,45 +1565,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "katexit"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1304c448ce2c207c2298a34bc476ce7ae47f63c23fa2b498583b26be9bc88c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "khronos_api"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||
|
||||
[[package]]
|
||||
name = "lapack-sys"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447f56c85fb410a7a3d36701b2153c1018b1d2b908c5fbaf01c1b04fac33bcbe"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lax"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f96a229d9557112e574164f8024ce703625ad9f88a90964c1780809358e53da"
|
||||
dependencies = [
|
||||
"cauchy",
|
||||
"katexit",
|
||||
"lapack-sys",
|
||||
"num-traits",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -1710,6 +1645,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.3.7"
|
||||
@ -1796,7 +1740,7 @@ version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511"
|
||||
dependencies = [
|
||||
"approx 0.5.1",
|
||||
"approx",
|
||||
"matrixmultiply",
|
||||
"nalgebra-macros",
|
||||
"num-complex",
|
||||
@ -1804,7 +1748,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"serde",
|
||||
"simba",
|
||||
"typenum",
|
||||
]
|
||||
@ -1830,39 +1773,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndarray"
|
||||
version = "0.15.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
|
||||
dependencies = [
|
||||
"approx 0.4.0",
|
||||
"cblas-sys",
|
||||
"libc",
|
||||
"matrixmultiply",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rawpointer",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndarray-linalg"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b0e8dda0c941b64a85c5deb2b3e0144aca87aced64678adfc23eacea6d2cc42"
|
||||
dependencies = [
|
||||
"cauchy",
|
||||
"katexit",
|
||||
"lax",
|
||||
"ndarray",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.7.0"
|
||||
@ -1946,6 +1856,16 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.3"
|
||||
@ -1953,8 +1873,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2120,6 +2038,12 @@ version = "6.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.19.0"
|
||||
@ -2412,9 +2336,24 @@ checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.1"
|
||||
@ -2576,13 +2515,22 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae"
|
||||
dependencies = [
|
||||
"approx 0.5.1",
|
||||
"approx",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"paste",
|
||||
@ -2611,6 +2559,10 @@ dependencies = [
|
||||
"nohash-hasher",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"tracing",
|
||||
"tracing-chrome",
|
||||
"tracing-error",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2944,6 +2896,17 @@ dependencies = [
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-chrome"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "496b3cd5447f7ff527bbbf19b071ad542a000adf297d4127078b4dfdb931f41a"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
@ -2951,6 +2914,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-error"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3017,6 +3020,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
argmin = { version = "0.8.1", features = [] }
|
||||
argmin-math = { version = "0.3.0", features = ["latest_all"] }
|
||||
argmin-math = { version = "0.3.0", features = ["nalgebra_v0_32"] }
|
||||
bevy_ecs = "0.10.1"
|
||||
eframe = { version = "0.21.3" }
|
||||
indexmap = "1.8.1"
|
||||
@ -17,7 +17,13 @@ nalgebra-sparse = "0.9.0"
|
||||
nohash-hasher = "0.2.0"
|
||||
rand = "0.8.5"
|
||||
rand_distr = "0.4.3"
|
||||
tracing = { version = "0.1.37", optional = true }
|
||||
tracing-chrome = { version = "0.7.1", optional = true }
|
||||
tracing-error = { version = "0.2.0", optional = true }
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.4.0"
|
||||
|
||||
[features]
|
||||
trace = ["tracing", "tracing-subscriber", "tracing-chrome", "tracing-error", "bevy_ecs/trace"]
|
||||
|
379
src/main.rs
379
src/main.rs
@ -15,380 +15,8 @@ use geometry::{Line, LineBundle, Point, PointId, PointPos, PointPosQueryMut};
|
||||
mod geometry;
|
||||
pub mod optimization;
|
||||
mod relations;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Resource)]
|
||||
enum Tool {
|
||||
Select,
|
||||
Move,
|
||||
AddPoint,
|
||||
AddLine,
|
||||
AddRelation,
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for Tool {
|
||||
fn default() -> Self {
|
||||
Tool::Select
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct ResponseRes(Response);
|
||||
|
||||
impl Deref for ResponseRes {
|
||||
type Target = Response;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct PainterRes(Painter);
|
||||
|
||||
impl Deref for PainterRes {
|
||||
type Target = Painter;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
impl DerefMut for PainterRes {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct ToScreen(RectTransform);
|
||||
|
||||
impl ToScreen {
|
||||
fn transform_pos(&self, pos: &PointPos) -> Pos2 {
|
||||
self.0 * Pos2::new(pos.x as f32, pos.y as f32)
|
||||
}
|
||||
|
||||
fn inverse_transform(&self, pos: Pos2) -> Pos2 {
|
||||
self.0.inverse() * pos
|
||||
}
|
||||
|
||||
fn inverse_transform_to_point(&self, pos: Pos2) -> PointPos {
|
||||
let pos = self.inverse_transform(pos);
|
||||
PointPos::new(pos.x as f64, pos.y as f64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct Hovered;
|
||||
|
||||
#[derive(Component)]
|
||||
struct Selected;
|
||||
|
||||
fn color_for_var_status(status: geometry::VarStatus) -> Hsva {
|
||||
use geometry::VarStatus::*;
|
||||
match status {
|
||||
Free => Hsva::new(200. / 360., 0.90, 0.80, 1.0),
|
||||
Dependent => todo!(),
|
||||
Unique => todo!(),
|
||||
Overconstrained => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
const POINT_RADIUS: f32 = 3.0;
|
||||
|
||||
fn update_hover_point(
|
||||
response: Res<ResponseRes>,
|
||||
to_screen: Res<ToScreen>,
|
||||
points: Query<(PointId, &geometry::ComputedPointPos)>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
points.for_each(|(id, pos)| {
|
||||
let hovered = if let Some(hover_pos) = response.hover_pos() {
|
||||
let center = to_screen.transform_pos(pos);
|
||||
|
||||
(hover_pos - center).length() < (POINT_RADIUS * 3.)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if hovered {
|
||||
commands.entity(id).insert(Hovered);
|
||||
} else {
|
||||
commands.entity(id).remove::<Hovered>();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn update_hover_line(
|
||||
response: Res<ResponseRes>,
|
||||
to_screen: Res<ToScreen>,
|
||||
lines: Query<(Entity, &geometry::ComputedLinePos)>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
lines.for_each(|(id, pos)| {
|
||||
let hovered = if let Some(hover_pos) = response.hover_pos() {
|
||||
let points = [
|
||||
to_screen.transform_pos(&pos.start),
|
||||
to_screen.transform_pos(&pos.end),
|
||||
];
|
||||
|
||||
let b = points[1] - points[0];
|
||||
let a = hover_pos - points[0];
|
||||
let p = a.dot(b) / b.dot(b);
|
||||
let perp = a - (p * b);
|
||||
((0.)..=1.).contains(&p) && perp.length() < 5.0
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if hovered {
|
||||
commands.entity(id).insert(Hovered);
|
||||
} else {
|
||||
commands.entity(id).remove::<Hovered>();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn select_tool(
|
||||
response: Res<ResponseRes>,
|
||||
hovered: Query<Entity, With<Hovered>>,
|
||||
selected: Query<Entity, With<Selected>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
response.ctx.output_mut(|output| {
|
||||
output.cursor_icon = if !hovered.is_empty() {
|
||||
CursorIcon::PointingHand
|
||||
} else {
|
||||
CursorIcon::Default
|
||||
}
|
||||
});
|
||||
|
||||
if response.clicked() {
|
||||
if !response.ctx.input(|input| input.modifiers.shift) {
|
||||
selected.for_each(|selected| {
|
||||
commands.entity(selected).remove::<Selected>();
|
||||
});
|
||||
}
|
||||
// TODO: choose which to select
|
||||
if let Some(hovered) = hovered.iter().next() {
|
||||
commands.entity(hovered).insert(Selected);
|
||||
}
|
||||
}
|
||||
|
||||
if response
|
||||
.ctx
|
||||
.input(|input| input.key_pressed(egui::Key::Escape))
|
||||
{
|
||||
selected.for_each(|selected| {
|
||||
commands.entity(selected).remove::<Selected>();
|
||||
});
|
||||
} else if response
|
||||
.ctx
|
||||
.input(|input| input.key_pressed(egui::Key::Delete))
|
||||
{
|
||||
selected.for_each(|selected| {
|
||||
commands.entity(selected).despawn();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct DragDelta(Vec2);
|
||||
|
||||
// TODO: move other entities
|
||||
fn move_tool(
|
||||
response: Res<ResponseRes>,
|
||||
to_screen: Res<ToScreen>,
|
||||
mut drag_delta: Local<DragDelta>,
|
||||
mut point_pos: PointPosQueryMut,
|
||||
hovered: Query<(Entity, &Point), With<Hovered>>,
|
||||
selected: Query<(Entity, &Point), With<Selected>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
let hover_pos = response.hover_pos().unwrap();
|
||||
|
||||
response.ctx.output_mut(|o| {
|
||||
o.cursor_icon = if !selected.is_empty() {
|
||||
CursorIcon::Grabbing
|
||||
} else if !hovered.is_empty() {
|
||||
CursorIcon::Grab
|
||||
} else {
|
||||
CursorIcon::Move
|
||||
}
|
||||
});
|
||||
|
||||
let selected = if response.drag_started() {
|
||||
// TODO: choose which to select
|
||||
let to_select = hovered.iter().next();
|
||||
if let Some(hovered) = to_select {
|
||||
commands.entity(hovered.0).insert(Selected);
|
||||
}
|
||||
to_select
|
||||
} else if response.drag_released() {
|
||||
selected.for_each(|selected| {
|
||||
commands.entity(selected.0).remove::<Selected>();
|
||||
});
|
||||
drag_delta.0 = Vec2::ZERO;
|
||||
None
|
||||
} else {
|
||||
selected.iter().next()
|
||||
};
|
||||
|
||||
if let Some((_, point)) = selected {
|
||||
if response.drag_started() {
|
||||
let drag_point_pos = point_pos.get(point).unwrap();
|
||||
drag_delta.0 = hover_pos - to_screen.transform_pos(&drag_point_pos);
|
||||
}
|
||||
let move_to = to_screen.inverse_transform_to_point(hover_pos - drag_delta.0);
|
||||
point_pos.set(point, move_to).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn add_point(commands: &mut Commands, pos: Pos2, to_screen: &ToScreen) -> PointId {
|
||||
let point_pos = to_screen.inverse_transform(pos);
|
||||
let point_pos = (point_pos.x as f64, point_pos.y as f64);
|
||||
geometry::insert_point_at(commands, point_pos)
|
||||
}
|
||||
|
||||
fn add_point_tool(
|
||||
response: Res<ResponseRes>,
|
||||
to_screen: Res<ToScreen>,
|
||||
painter: ResMut<PainterRes>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
let hover_pos = response.hover_pos().unwrap();
|
||||
if response.clicked() {
|
||||
add_point(&mut commands, hover_pos, &to_screen);
|
||||
} else {
|
||||
painter.circle_filled(hover_pos, POINT_RADIUS, Color32::WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_line_tool(
|
||||
response: Res<ResponseRes>,
|
||||
to_screen: Res<ToScreen>,
|
||||
painter: ResMut<PainterRes>,
|
||||
hovered: Query<Entity, (With<Hovered>, With<Point>)>,
|
||||
selected: Query<(Entity, &geometry::ComputedPointPos), With<Selected>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
let hover_pos = response.hover_pos().unwrap();
|
||||
|
||||
match (selected.iter().next(), response.clicked()) {
|
||||
(None, false) => {
|
||||
painter.circle_filled(hover_pos, POINT_RADIUS, Color32::DARK_GRAY);
|
||||
}
|
||||
(None, true) => {
|
||||
let point_id = match hovered.iter().next() {
|
||||
Some(hovered) => hovered,
|
||||
None => add_point(&mut commands, hover_pos, &to_screen),
|
||||
};
|
||||
commands.entity(point_id).insert(Selected);
|
||||
}
|
||||
(Some((_, start_point_pos)), false) => {
|
||||
let points = [to_screen.transform_pos(start_point_pos), hover_pos];
|
||||
|
||||
let stroke = Stroke::new(2.0, Color32::DARK_GRAY);
|
||||
|
||||
painter.line_segment(points, stroke);
|
||||
|
||||
painter.circle_filled(hover_pos, POINT_RADIUS, Color32::DARK_GRAY);
|
||||
}
|
||||
(Some((start_point_id, _)), true) => {
|
||||
// TODO: add point if no hover point
|
||||
let end_point = hovered
|
||||
.iter()
|
||||
.next()
|
||||
.unwrap_or_else(|| add_point(&mut commands, hover_pos, &to_screen));
|
||||
|
||||
let line = LineBundle::new(start_point_id, end_point);
|
||||
commands.spawn(line);
|
||||
|
||||
selected.for_each(|(selected_id, _)| {
|
||||
commands.entity(selected_id).remove::<Selected>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_relation_tool(
|
||||
response: Res<ResponseRes>,
|
||||
hovered: Query<Entity, With<Hovered>>,
|
||||
selected: Query<Entity, With<Selected>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
response.ctx.output_mut(|o| {
|
||||
o.cursor_icon = if !hovered.is_empty() {
|
||||
CursorIcon::PointingHand
|
||||
} else {
|
||||
CursorIcon::Default
|
||||
}
|
||||
});
|
||||
|
||||
if response.clicked() {
|
||||
// TODO: choose which to select
|
||||
if let Some(hovered) = hovered.iter().next() {
|
||||
commands.entity(hovered).insert(Selected);
|
||||
} else {
|
||||
selected.for_each(|selected| {
|
||||
commands.entity(selected).remove::<Selected>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_hovered(response: Res<ResponseRes>) -> bool {
|
||||
response.hover_pos().is_some()
|
||||
}
|
||||
|
||||
fn is_tool_active(tool: Tool) -> impl System<In = (), Out = bool> + ReadOnlySystem {
|
||||
IntoSystem::into_system(move |active_tool: Res<Tool>| *active_tool == tool)
|
||||
}
|
||||
|
||||
fn paint_lines(
|
||||
to_screen: Res<ToScreen>,
|
||||
painter: ResMut<PainterRes>,
|
||||
lines: Query<(Entity, &geometry::ComputedLinePos)>,
|
||||
hovered: Query<(), With<Hovered>>,
|
||||
selected: Query<(), With<Selected>>,
|
||||
) {
|
||||
lines.for_each(|(id, pos)| {
|
||||
let points = [
|
||||
to_screen.transform_pos(&pos.start),
|
||||
to_screen.transform_pos(&pos.end),
|
||||
];
|
||||
|
||||
let mut color = color_for_var_status(pos.status);
|
||||
color.v -= 0.6;
|
||||
if hovered.contains(id) || selected.contains(id) {
|
||||
color.s -= 0.8;
|
||||
}
|
||||
|
||||
let stroke = Stroke::new(2.0, color);
|
||||
|
||||
painter.line_segment(points, stroke);
|
||||
});
|
||||
}
|
||||
|
||||
fn paint_points(
|
||||
to_screen: Res<ToScreen>,
|
||||
painter: ResMut<PainterRes>,
|
||||
points: Query<(Entity, &geometry::ComputedPointPos)>,
|
||||
hovered: Query<(), With<Hovered>>,
|
||||
selected: Query<(), With<Selected>>,
|
||||
) {
|
||||
points.for_each(|(id, pos)| {
|
||||
let center = to_screen.transform_pos(pos);
|
||||
|
||||
let color = color_for_var_status(pos.status);
|
||||
let stroke = if selected.contains(id) || hovered.contains(id) {
|
||||
// color.s -= 0.8;
|
||||
Stroke::new(1.0, Color32::WHITE)
|
||||
} else {
|
||||
Stroke::default()
|
||||
};
|
||||
painter.circle(center, POINT_RADIUS, color, stroke);
|
||||
});
|
||||
}
|
||||
#[cfg(feature = "trace")]
|
||||
mod tracing;
|
||||
|
||||
fn init(mut commands: Commands) {
|
||||
let p1 = geometry::insert_point_at(&mut commands, (10., 30.));
|
||||
@ -607,7 +235,8 @@ impl MyApp {
|
||||
fn new() -> Self {
|
||||
let mut world = World::default();
|
||||
|
||||
world.init_resource::<Tool>();
|
||||
#[cfg(feature = "trace")]
|
||||
tracing::setup(&mut world);
|
||||
|
||||
let mut init_sched = Schedule::new();
|
||||
init_sched.add_system(init);
|
||||
|
50
src/tracing.rs
Normal file
50
src/tracing.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use std::panic;
|
||||
|
||||
use bevy_ecs::world::World;
|
||||
use tracing::Level;
|
||||
use tracing_subscriber::{
|
||||
fmt::{format::DefaultFields, FormattedFields},
|
||||
prelude::*,
|
||||
EnvFilter, Registry,
|
||||
};
|
||||
|
||||
pub fn setup(world: &mut World) {
|
||||
let old_handler = panic::take_hook();
|
||||
panic::set_hook(Box::new(move |infos| {
|
||||
println!("{}", tracing_error::SpanTrace::capture());
|
||||
old_handler(infos);
|
||||
}));
|
||||
|
||||
let default_filter = { format!("{},{}", Level::INFO, "") };
|
||||
let filter_layer = EnvFilter::try_from_default_env()
|
||||
.or_else(|_| EnvFilter::try_new(&default_filter))
|
||||
.unwrap();
|
||||
let subscriber = Registry::default().with(filter_layer);
|
||||
|
||||
let subscriber = subscriber.with(tracing_error::ErrorLayer::default());
|
||||
|
||||
let chrome_layer = {
|
||||
let mut layer = tracing_chrome::ChromeLayerBuilder::new();
|
||||
if let Ok(path) = std::env::var("TRACE_CHROME") {
|
||||
layer = layer.file(path);
|
||||
}
|
||||
let (chrome_layer, guard) = layer
|
||||
.name_fn(Box::new(|event_or_span| match event_or_span {
|
||||
tracing_chrome::EventOrSpan::Event(event) => event.metadata().name().into(),
|
||||
tracing_chrome::EventOrSpan::Span(span) => {
|
||||
if let Some(fields) = span.extensions().get::<FormattedFields<DefaultFields>>()
|
||||
{
|
||||
format!("{}: {}", span.metadata().name(), fields.fields.as_str())
|
||||
} else {
|
||||
span.metadata().name().into()
|
||||
}
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
world.insert_non_send_resource(guard);
|
||||
chrome_layer
|
||||
};
|
||||
let subscriber = subscriber.with(chrome_layer);
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user