show dialog on panic
This commit is contained in:
parent
43b8e75ad7
commit
2d4736f12e
6 changed files with 319 additions and 6 deletions
153
Cargo.lock
generated
153
Cargo.lock
generated
|
@ -139,6 +139,12 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
|
||||
|
||||
[[package]]
|
||||
name = "ascii"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.38.0+1.3.281"
|
||||
|
@ -351,6 +357,36 @@ dependencies = [
|
|||
"error-code",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa-foundation"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"block",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"libc",
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
|
@ -1101,6 +1137,15 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
|
@ -1277,6 +1322,12 @@ dependencies = [
|
|||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.5"
|
||||
|
@ -1308,6 +1359,29 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-dialog"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84e7038885d2aeab236bd60da9e159a5967b47cde3292da3b15ff1bec27c039f"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"block",
|
||||
"cocoa",
|
||||
"core-foundation",
|
||||
"dirs-next",
|
||||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"once_cell",
|
||||
"raw-window-handle 0.5.2",
|
||||
"thiserror 1.0.69",
|
||||
"versions",
|
||||
"wfd",
|
||||
"which",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.9.0"
|
||||
|
@ -1319,7 +1393,7 @@ dependencies = [
|
|||
"log",
|
||||
"ndk-sys 0.6.0+11769913",
|
||||
"num_enum",
|
||||
"raw-window-handle",
|
||||
"raw-window-handle 0.6.2",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
|
@ -1368,6 +1442,16 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
@ -1417,6 +1501,17 @@ dependencies = [
|
|||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-foundation"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
|
||||
dependencies = [
|
||||
"block",
|
||||
"objc",
|
||||
"objc_id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.5"
|
||||
|
@ -1620,6 +1715,15 @@ dependencies = [
|
|||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_id"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
|
||||
dependencies = [
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
|
@ -1868,6 +1972,12 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.2"
|
||||
|
@ -2555,6 +2665,16 @@ version = "0.9.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "versions"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
|
@ -2771,6 +2891,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wfd"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e713040b67aae5bf1a0ae3e1ebba8cc29ab2b90da9aa1bff6e09031a8a41d7a8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wgpu"
|
||||
version = "24.0.3"
|
||||
|
@ -2786,7 +2916,7 @@ dependencies = [
|
|||
"naga",
|
||||
"parking_lot",
|
||||
"profiling",
|
||||
"raw-window-handle",
|
||||
"raw-window-handle 0.6.2",
|
||||
"smallvec",
|
||||
"static_assertions",
|
||||
"wasm-bindgen",
|
||||
|
@ -2814,7 +2944,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"parking_lot",
|
||||
"profiling",
|
||||
"raw-window-handle",
|
||||
"raw-window-handle 0.6.2",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
"thiserror 2.0.12",
|
||||
|
@ -2856,7 +2986,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"profiling",
|
||||
"range-alloc",
|
||||
"raw-window-handle",
|
||||
"raw-window-handle 0.6.2",
|
||||
"renderdoc-sys",
|
||||
"rustc-hash 1.1.0",
|
||||
"smallvec",
|
||||
|
@ -2892,6 +3022,18 @@ dependencies = [
|
|||
"wgpu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix 0.38.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -3237,7 +3379,7 @@ dependencies = [
|
|||
"orbclient",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"raw-window-handle",
|
||||
"raw-window-handle 0.6.2",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix 0.38.44",
|
||||
"sctk-adwaita",
|
||||
|
@ -3397,6 +3539,7 @@ dependencies = [
|
|||
"dirs-next",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"native-dialog",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
|
|
|
@ -42,3 +42,4 @@ typenum = { version = "1.18.0", features = ["const-generics"] }
|
|||
tobj = { version = "4.0.3", features = ["tokio"] }
|
||||
ahash = "0.8.11"
|
||||
wgpu_text = "0.9.2"
|
||||
native-dialog = "0.7.0"
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use std::any::{Any, TypeId};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub trait Component: Sized + 'static {
|
||||
fn update(&mut self, delta_time: f32);
|
||||
fn serialize(&self) -> Vec<u8>;
|
||||
|
@ -11,3 +15,156 @@ pub trait Entity: Sized {
|
|||
fn serialize(&self) -> Vec<u8>;
|
||||
fn deserialize(data: &[u8; 6]) -> Self;
|
||||
}
|
||||
lazy_static::lazy_static! {
|
||||
// Global registry mapping component TypeId to a unique bit flag.
|
||||
static ref COMPONENT_REGISTRY: Mutex<HashMap<TypeId, u64>> = Mutex::new(HashMap::new());
|
||||
static ref NEXT_COMPONENT_BIT: Mutex<u64> = Mutex::new(1);
|
||||
}
|
||||
|
||||
// To allow dynamic dispatch on components (even though Component itself is not object‐safe)
|
||||
// we wrap them in an object–safe trait.
|
||||
pub trait ComponentObject: Any {
|
||||
fn update_obj(&mut self, delta_time: f32);
|
||||
fn serialize_obj(&self) -> Vec<u8>;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
impl<T: Component + 'static> ComponentObject for T {
|
||||
fn update_obj(&mut self, delta_time: f32) {
|
||||
T::update(self, delta_time)
|
||||
}
|
||||
fn serialize_obj(&self) -> Vec<u8> {
|
||||
T::serialize(self)
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EntityImpl {
|
||||
id: usize,
|
||||
bitmask: u64,
|
||||
// The key is the unique bit flag for the component type.
|
||||
components: HashMap<u64, Box<dyn ComponentObject>>,
|
||||
}
|
||||
|
||||
impl EntityImpl {
|
||||
pub fn new(id: usize) -> Self {
|
||||
EntityImpl {
|
||||
id,
|
||||
bitmask: 0,
|
||||
components: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for EntityImpl {
|
||||
fn add_component<C: Component>(&mut self, component: C) {
|
||||
let type_id = TypeId::of::<C>();
|
||||
let mut registry = COMPONENT_REGISTRY.lock().unwrap();
|
||||
let bit = registry.entry(type_id).or_insert_with(|| {
|
||||
let mut next_bit = NEXT_COMPONENT_BIT.lock().unwrap();
|
||||
let current = *next_bit;
|
||||
*next_bit *= 2;
|
||||
current
|
||||
});
|
||||
self.bitmask |= *bit;
|
||||
self.components.insert(*bit, Box::new(component));
|
||||
}
|
||||
|
||||
fn remove_component<C: Component>(&mut self) {
|
||||
let type_id = TypeId::of::<C>();
|
||||
if let Some(&bit) = COMPONENT_REGISTRY.lock().unwrap().get(&type_id) {
|
||||
self.bitmask &= !bit;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_component<C: Component>(&self) -> Option<&C> {
|
||||
let type_id = TypeId::of::<C>();
|
||||
if let Some(&bit) = COMPONENT_REGISTRY.lock().unwrap().get(&type_id) {
|
||||
self.components.get(&bit)
|
||||
.and_then(|boxed| boxed.as_any().downcast_ref::<C>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Vec<u8> {
|
||||
// Serialize the entity's bitmask into 6 bytes (lowest 48 bits).
|
||||
let mut bytes = self.bitmask.to_le_bytes().to_vec();
|
||||
bytes.truncate(6);
|
||||
bytes
|
||||
}
|
||||
|
||||
fn deserialize(data: &[u8; 6]) -> Self {
|
||||
let mut full = [0u8; 8];
|
||||
full[..6].copy_from_slice(data);
|
||||
let bitmask = u64::from_le_bytes(full);
|
||||
// When deserializing, we recreate an entity with the restored bitmask.
|
||||
// Note: The individual component data are not restored here.
|
||||
Self {
|
||||
id: 0,
|
||||
bitmask,
|
||||
components: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct ECS {
|
||||
next_entity_id: usize,
|
||||
pub entities: HashMap<usize, EntityImpl>,
|
||||
}
|
||||
|
||||
impl ECS {
|
||||
pub fn new() -> Self {
|
||||
ECS {
|
||||
next_entity_id: 0,
|
||||
entities: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_entity(&mut self) -> &mut EntityImpl {
|
||||
let entity = EntityImpl::new(self.next_entity_id);
|
||||
self.entities.insert(self.next_entity_id, entity);
|
||||
self.next_entity_id += 1;
|
||||
self.entities.get_mut(&(self.next_entity_id - 1)).unwrap()
|
||||
}
|
||||
|
||||
pub fn update(&mut self, delta_time: f32) {
|
||||
for entity in self.entities.values_mut() {
|
||||
// Update each component attached to the entity.
|
||||
for comp in entity.components.values_mut() {
|
||||
comp.update_obj(delta_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut data = Vec::new();
|
||||
// For each entity, store its id (8 bytes) and its 6-byte bitmask.
|
||||
for (id, entity) in &self.entities {
|
||||
data.extend_from_slice(&id.to_le_bytes());
|
||||
data.extend_from_slice(&entity.serialize());
|
||||
}
|
||||
data
|
||||
}
|
||||
|
||||
pub fn deserialize(&mut self, data: &[u8]) {
|
||||
self.entities.clear();
|
||||
// Each serialized entity uses 8 (id) + 6 (bitmask) = 14 bytes.
|
||||
let entity_size = 14;
|
||||
let count = data.len() / entity_size;
|
||||
for i in 0..count {
|
||||
let offset = i * entity_size;
|
||||
let mut id_bytes = [0u8; 8];
|
||||
id_bytes.copy_from_slice(&data[offset..offset + 8]);
|
||||
let id = usize::from_le_bytes(id_bytes);
|
||||
|
||||
let mut mask_bytes = [0u8; 6];
|
||||
mask_bytes.copy_from_slice(&data[offset + 8..offset + 14]);
|
||||
let entity = EntityImpl::deserialize(&mask_bytes);
|
||||
self.entities.insert(id, entity);
|
||||
}
|
||||
self.next_entity_id = count;
|
||||
}
|
||||
}
|
|
@ -3,8 +3,10 @@ use std::fmt::Write as FmtWrite;
|
|||
use std::mem;
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use native_dialog::{MessageDialog, MessageType};
|
||||
use parking_lot::Once;
|
||||
use regex::Regex;
|
||||
use tracing::error;
|
||||
|
||||
static INIT: parking_lot::Once = Once::new();
|
||||
|
||||
|
@ -48,7 +50,7 @@ fn process_panic(info: &std::panic::PanicHookInfo<'_>) -> Result<(), Box<dyn Err
|
|||
let panic_msg = format!(
|
||||
"Zenyx had a problem and crashed. To help us diagnose the problem you can send us a crash report.
|
||||
|
||||
We have generated a report file at \"{}\". Submit an issue or email with the subject of \"Zenyx Crash Report\" and include the report as an attachment.
|
||||
We have generated a report file at '{}'. Submit an issue or email with the subject of 'Zenyx Crash Report' and include the report as an attachment.
|
||||
|
||||
To submit the crash report:
|
||||
|
||||
|
@ -62,6 +64,14 @@ Thank you kindly!", log_path.display());
|
|||
"\nFor future reference, the error summary is as follows:\n{}",
|
||||
payload_str.red().bold()
|
||||
);
|
||||
if let Err(e ) = MessageDialog::new()
|
||||
.set_type(MessageType::Error)
|
||||
.set_title(&format!("{}",payload_str))
|
||||
// wont display properly if not debug formatted??
|
||||
.set_text(&format!("{:#?}", panic_msg))
|
||||
.show_alert() {
|
||||
error!("{e}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
info!("{}", "Debug mode disabled".bright_blue());
|
||||
set_panic_hook();
|
||||
}
|
||||
set_panic_hook();
|
||||
setup();
|
||||
|
||||
let repl_thread = std::thread::spawn(|| {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
xorg.libX11
|
||||
xorg.libxcb
|
||||
pkg-config
|
||||
kdePackages.kdialog
|
||||
];
|
||||
in {
|
||||
packages = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue