//! Internal engine state — not part of the public FFI API. //! //! The [`Engine`] struct bundles an open [`Database`] connection and a //! [`Hlc`] (Hybrid Logical Clock) for the local node. A single global //! instance is held behind a [`Mutex`] so that FRB's thread-pool workers //! can safely share access. use std::sync::Mutex; use chronogrid_core::{Database, Hlc}; /// Runtime engine holding the encrypted database and the node's HLC. pub(crate) struct Engine { /// Encrypted SQLCipher database connection with ChronoGrid schema. pub(crate) db: Database, /// Hybrid Logical Clock for causally ordered CRDT mutations. pub(crate) hlc: Hlc, } /// Global engine singleton. /// /// `None` before [`super::engine::init_engine`] is called, `Some` while the /// engine is active, and `None` again after [`super::engine::close_engine`]. pub(crate) static ENGINE: Mutex> = Mutex::new(None); // ── Convenience helpers ────────────────────────────────────────────────────── /// Acquires the engine lock and calls `f` with a shared reference. /// /// Returns `Err` if the engine has not been initialized or the lock is /// poisoned. pub(crate) fn with_engine( f: impl FnOnce(&Engine) -> anyhow::Result, ) -> anyhow::Result { let guard = ENGINE .lock() .map_err(|e| anyhow::anyhow!("engine lock poisoned: {e}"))?; let engine = guard .as_ref() .ok_or_else(|| anyhow::anyhow!("engine not initialized — call init_engine first"))?; f(engine) } /// Acquires the engine lock and calls `f` with a mutable reference. /// /// Returns `Err` if the engine has not been initialized or the lock is /// poisoned. pub(crate) fn with_engine_mut( f: impl FnOnce(&mut Engine) -> anyhow::Result, ) -> anyhow::Result { let mut guard = ENGINE .lock() .map_err(|e| anyhow::anyhow!("engine lock poisoned: {e}"))?; let engine = guard .as_mut() .ok_or_else(|| anyhow::anyhow!("engine not initialized — call init_engine first"))?; f(engine) }