use abstracttui::prelude::*;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::WINDOW;
pub fn hash(n: u64) -> u64 {
(n ^ 0x9E37_79B9_7F4A_7C15)
.wrapping_mul(0xC2B2_AE3D_27D4_EB4F)
.rotate_left(23)
.wrapping_mul(0x2545_F491_4F6C_DD1D)
}
pub fn hash01(n: u64) -> f32 {
(hash(n) >> 40) as f32 / (1u64 << 24) as f32
}
pub fn sample(now: u64, i: usize, phase: f32, speed: f32, base: f32, amp: f32, noise: f32) -> f32 {
let t = now.saturating_sub((WINDOW - 1 - i) as u64) as f32;
base + amp * (t * speed + phase).sin() + noise * (hash01(t as u64 + phase as u64) - 0.5)
}
pub fn rx_at(now: u64, i: usize) -> f32 {
(sample(now, i, 0.0, 0.11, 52.0, 28.0, 14.0)).clamp(0.0, 100.0)
}
pub fn tx_at(now: u64, i: usize) -> f32 {
(sample(now, i, 2.1, 0.07, 30.0, 16.0, 10.0)).clamp(0.0, 100.0)
}
pub fn cpu_at(now: u64, i: usize) -> f32 {
(sample(now, i, 0.7, 0.13, 0.52, 0.34, 0.10)).clamp(0.02, 1.0)
}
pub fn mem_at(now: u64, i: usize) -> f32 {
(sample(now, i, 4.2, 0.03, 0.63, 0.12, 0.04)).clamp(0.02, 1.0)
}
pub fn io_at(now: u64, i: usize) -> f32 {
let burst = if hash(now.saturating_sub((WINDOW - 1 - i) as u64) / 16).is_multiple_of(5) {
0.35
} else {
0.0
};
(sample(now, i, 1.3, 0.19, 0.28, 0.14, 0.12) + burst).clamp(0.02, 1.0)
}
pub fn clock_text() -> String {
let secs = std::env::var("ABSTRACTTUI_FIXED_CLOCK")
.ok()
.and_then(|v| v.parse::<u64>().ok())
.unwrap_or_else(|| {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
});
format!(
"{:02}:{:02}:{:02} UTC",
(secs / 3600) % 24,
(secs / 60) % 60,
secs % 60
)
}
pub fn guard_layout() -> LayoutStyle {
LayoutStyle::default().absolute(abstracttui::layout::Inset {
left: Some(0),
right: Some(0),
top: Some(0),
bottom: Some(0),
})
}
pub fn session_rows(now: u64) -> Vec<Vec<String>> {
const HOSTS: [(&str, &str); 7] = [
("edge-1", "eu-w"),
("edge-2", "eu-w"),
("edge-3", "us-e"),
("core-a", "us-e"),
("core-b", "ap-s"),
("cache-1", "eu-n"),
("cache-2", "ap-s"),
];
HOSTS
.iter()
.enumerate()
.map(|(i, (host, region))| {
let rx = 8.0 + 40.0 * hash01(now.wrapping_add(i as u64 * 13));
let tx = 4.0 + 22.0 * hash01(now.wrapping_add(i as u64 * 29 + 5));
let state = match hash(now.wrapping_add(i as u64 * 43)) % 12 {
0 => "draining",
1 | 2 => "syncing",
_ => "healthy",
};
vec![
host.to_string(),
region.to_string(),
format!("{rx:.1} MB/s"),
format!("{tx:.1} MB/s"),
state.to_string(),
]
})
.collect()
}
pub fn log_line(t: &TokenSet, idx: u64) -> (&'static str, Rgba, &'static str) {
let entries: [(&'static str, Rgba, &'static str); 12] = [
("info", t.info, "session opened from edge-3"),
("info", t.info, "cache warmed in 412ms"),
("info", t.info, "checkpoint flushed"),
("info", t.info, "config reloaded (rev 41)"),
("info", t.info, "session opened from core-a"),
("ok", t.ok, "tls renewed for gateway"),
("ok", t.ok, "shard 2 caught up"),
("ok", t.ok, "backup verified"),
("warn", t.warn, "retry budget at 70%"),
("warn", t.warn, "backpressure on shard 2"),
("error", t.error, "edge-2 heartbeat missed"),
("error", t.error, "flush timed out, retrying"),
];
let n = entries.len() as u64;
let pick = hash(idx) % n;
let prev = hash(idx.wrapping_sub(1)) % n;
let pick = if pick == prev { (pick + 5) % n } else { pick };
entries[pick as usize]
}
pub fn brandmark_model() -> abstracttui::three::Model {
use abstracttui::boot::identity::brand_ramp;
use abstracttui::three::primitives::cuboid;
use abstracttui::three::texture::srgb8_to_linear;
use abstracttui::three::{Mat4, MaterialData, MeshInstance, Model, Vec3};
let mut instances = Vec::with_capacity(3);
for i in 0..3u32 {
let mut mesh = cuboid(if i == 2 { 0.7 } else { 1.0 }, 0.62, 0.04);
let colors = mesh
.positions
.iter()
.map(|p| {
let xn = (p[0] + 0.5).clamp(0.0, 1.0);
let c = brand_ramp((i as f32 + xn) / 3.0);
[
srgb8_to_linear(c.r),
srgb8_to_linear(c.g),
srgb8_to_linear(c.b),
1.0,
]
})
.collect();
mesh.colors = Some(colors);
mesh.material = Some(0);
let fi = i as f32 - 1.0;
let world = Mat4::translate(Vec3::new(0.0, (fi + 1.0) * 0.18, fi * 0.22))
.mul(&Mat4::rotate_x(12f32.to_radians()));
instances.push(MeshInstance {
data: mesh,
world,
source_node: None,
});
}
Model {
instances,
materials: vec![MaterialData::default()],
warnings: Vec::new(),
rig: None,
}
}