From f5a82152394fde4d8f740f664ab7737b82861618 Mon Sep 17 00:00:00 2001 From: cashmere Date: Tue, 28 Jul 2026 19:41:16 +0200 Subject: feat: GPUI desktop port foundation - scene crate: full project/scene/element model, serde round-trip proven against the web SerializedProject shape - transfer crate: .ocp zip container, cross-compat with web fflate archives proven in both directions - storage crate: filesystem project store replacing IndexedDB, .ocp import/export - media crate: ffmpeg-next 8 decoder (frames, audio, thumbnails, waveform summaries) - playback crate: wall-clock anchored, frame-rounded playback clock - gpu crate: native texture readback; compositor renders headless offscreen on Vulkan (spike test) - flake devshell: rust toolchain, GPUI native deps, ffmpeg dev, bindgen clang args; GPUI hello-world builds - port plan in notes/gpui-port.md --- rust/crates/animation/src/id.rs | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 rust/crates/animation/src/id.rs (limited to 'rust/crates/animation/src/id.rs') diff --git a/rust/crates/animation/src/id.rs b/rust/crates/animation/src/id.rs new file mode 100644 index 00000000..95288660 --- /dev/null +++ b/rust/crates/animation/src/id.rs @@ -0,0 +1,61 @@ +use std::cell::Cell; +use std::time::{SystemTime, UNIX_EPOCH}; + +thread_local! { + static RNG_STATE: Cell = const { Cell::new(0) }; +} + +fn next_u64() -> u64 { + RNG_STATE.with(|state| { + let mut value = state.get(); + if value == 0 { + let nanos = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_nanos() as u64) + .unwrap_or(0x9e37_79b9_7f4a_7c15); + value = nanos + ^ (std::process::id() as u64).rotate_left(32) + ^ 0x9e37_79b9_7f4a_7c15; + } + value ^= value << 13; + value ^= value >> 7; + value ^= value << 17; + state.set(value); + value + }) +} + +pub fn generate_uuid() -> String { + let mut bytes = [0u8; 16]; + for chunk in bytes.chunks_mut(8) { + let random = next_u64().to_le_bytes(); + chunk.copy_from_slice(&random[..chunk.len()]); + } + bytes[6] = (bytes[6] & 0x0f) | 0x40; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + let hex: Vec = bytes.iter().map(|byte| format!("{byte:02x}")).collect(); + format!( + "{}-{}-{}-{}-{}", + hex[0..4].join(""), + hex[4..6].join(""), + hex[6..8].join(""), + hex[8..10].join(""), + hex[10..16].join("") + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn generates_uuid_shaped_unique_ids() { + let id = generate_uuid(); + let parts: Vec<&str> = id.split('-').collect(); + assert_eq!(parts.len(), 5); + assert_eq!(parts[0].len(), 8); + assert_eq!(parts[1].len(), 4); + assert_eq!(parts[4].len(), 12); + assert_ne!(generate_uuid(), generate_uuid()); + } +} -- cgit v1.3.1