use std::fs::OpenOptions;
use std::io::Write;
use std::path::PathBuf;
use std::sync::Mutex;
static LOG_PATH: Mutex<Option<PathBuf>> = Mutex::new(None);
fn log_path() -> PathBuf {
if let Ok(guard) = LOG_PATH.lock() {
if let Some(p) = guard.as_ref() {
return p.clone();
}
}
let p = dirs::config_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join("flatland")
.join("gfx-session.log");
if let Ok(mut guard) = LOG_PATH.lock() {
*guard = Some(p.clone());
}
p
}
pub fn install_panic_hook() {
let default = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
let msg = format!("PANIC: {info}");
eprintln!("{msg}");
session_log(&msg);
if let Some(loc) = info.location() {
session_log(&format!(" at {}:{}:{}", loc.file(), loc.line(), loc.column()));
}
default(info);
}));
}
pub fn session_log(line: &str) {
let path = log_path();
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let ts = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_millis())
.unwrap_or(0);
if let Ok(mut f) = OpenOptions::new().create(true).append(true).open(&path) {
let _ = writeln!(f, "[{ts}] {line}");
}
}