forked from 1b-agent/opencadstudio-upstream
Snapshot: V4 plugin API and host integration
This commit is contained in:
1 parent
448869ac35
commit
29c41a4041
36 files changed
+5463
-253
No files matched your search
@@ -0,0 +1,91 @@
|
||||
//! Host-side V4 snapshot manager.
|
||||
//!
|
||||
//! Maintains a per-tab shared-memory document view keyed by the stable
|
||||
//! `DocumentTab.id`. The manager is used by `src/plugin/v4_support.rs` to
|
||||
//! open, publish, and close V4 snapshots independently of the V3 reader path.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Mutex, OnceLock};
|
||||
|
||||
use acadrust::CadDocument;
|
||||
|
||||
use crate::shm::{DocumentSnapshotStore, DocumentViewDataV4, DocumentViewInfo};
|
||||
|
||||
static MANAGER: OnceLock<Mutex<HostV4SnapshotManager>> = OnceLock::new();
|
||||
|
||||
fn global_manager() -> &'static Mutex<HostV4SnapshotManager> {
|
||||
MANAGER.get_or_init(|| Mutex::new(HostV4SnapshotManager::new()))
|
||||
}
|
||||
|
||||
/// Per-tab V4 shared-memory snapshot manager.
|
||||
pub struct HostV4SnapshotManager {
|
||||
stores: HashMap<u64, DocumentSnapshotStore<DocumentViewDataV4>>,
|
||||
segment_size: usize,
|
||||
}
|
||||
|
||||
impl HostV4SnapshotManager {
|
||||
/// Create a new manager with the default segment size.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
stores: HashMap::new(),
|
||||
segment_size: default_segment_size(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Open (or refresh) the V4 snapshot for `tab_id` and return the view info.
|
||||
pub fn open(&mut self, tab_id: u64, doc: &CadDocument) -> Option<DocumentViewInfo> {
|
||||
let store = match self.stores.get_mut(&tab_id) {
|
||||
Some(store) => store,
|
||||
None => {
|
||||
let store = DocumentSnapshotStore::new(tab_id, self.segment_size).ok()?;
|
||||
self.stores.entry(tab_id).or_insert(store)
|
||||
}
|
||||
};
|
||||
if let Err(e) = store.publish(&doc.into()) {
|
||||
eprintln!("[host] failed to publish V4 document view for tab {tab_id}: {e}");
|
||||
return None;
|
||||
}
|
||||
Some(DocumentViewInfo {
|
||||
path: store.path().to_string_lossy().into_owned(),
|
||||
version: store.version(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Publish the latest document to the existing V4 snapshot for `tab_id`.
|
||||
/// Returns the updated view info if the snapshot exists.
|
||||
pub fn publish(&mut self, tab_id: u64, doc: &CadDocument) -> Option<DocumentViewInfo> {
|
||||
let store = self.stores.get_mut(&tab_id)?;
|
||||
if let Err(e) = store.publish(&doc.into()) {
|
||||
eprintln!("[host] failed to publish V4 document view for tab {tab_id}: {e}");
|
||||
return None;
|
||||
}
|
||||
Some(DocumentViewInfo {
|
||||
path: store.path().to_string_lossy().into_owned(),
|
||||
version: store.version(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Close the V4 snapshot for `tab_id`.
|
||||
pub fn close(&mut self, tab_id: u64) {
|
||||
self.stores.remove(&tab_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HostV4SnapshotManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Global accessor for the host V4 snapshot manager.
|
||||
pub fn manager() -> &'static Mutex<HostV4SnapshotManager> {
|
||||
global_manager()
|
||||
}
|
||||
|
||||
fn default_segment_size() -> usize {
|
||||
std::env::var("OCS_V4_SNAPSHOT_SEGMENT_SIZE")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(16 * 1024 * 1024)
|
||||
.max(1024 * 1024)
|
||||
}
|
||||
Reference in new issue
Block a user