Skip to main content

ass_editor/sessions/
manager.rs

1//! Multi-document session manager core.
2//!
3//! Defines [`EditorSessionManager`] and its private interior state, including
4//! construction, thread-safe interior-access helpers, and the [`Clone`] and
5//! [`core::fmt::Debug`] implementations. Session lifecycle and document-access
6//! operations live in the sibling [`lifecycle`](super::lifecycle) and
7//! [`access`](super::access) modules.
8
9use super::config::{SessionConfig, SessionStats};
10use super::session::EditorSession;
11
12#[cfg(feature = "arena")]
13use bumpalo::Bump;
14
15#[cfg(feature = "std")]
16use std::collections::HashMap;
17
18#[cfg(not(feature = "std"))]
19use alloc::collections::BTreeMap as HashMap;
20
21#[cfg(not(feature = "std"))]
22use alloc::{string::String, vec::Vec};
23
24#[cfg(feature = "multi-thread")]
25use std::sync::Arc;
26
27#[cfg(all(feature = "plugins", not(feature = "multi-thread")))]
28use std::sync::Arc;
29
30#[cfg(not(feature = "multi-thread"))]
31use core::cell::RefCell;
32
33#[cfg(feature = "multi-thread")]
34use parking_lot::Mutex;
35
36/// Multi-document session manager with resource sharing
37///
38/// Manages multiple editing sessions with shared resources like extension
39/// registries and arena allocators. Provides efficient session switching
40/// and automatic resource management.
41pub(super) struct EditorSessionManagerInner {
42    /// Configuration for this manager
43    pub(super) config: SessionConfig,
44
45    /// Active editing sessions
46    pub(super) sessions: HashMap<String, EditorSession>,
47
48    /// Currently active session ID
49    pub(super) active_session_id: Option<String>,
50
51    /// Shared arena allocator for temporary operations
52    #[cfg(feature = "arena")]
53    pub(super) shared_arena: Bump,
54
55    /// Shared extension registry
56    #[cfg(feature = "plugins")]
57    pub(super) extension_registry: Option<Arc<ass_core::plugin::ExtensionRegistry>>,
58
59    /// Statistics tracking
60    pub(super) stats: SessionStats,
61
62    /// Operations since last arena reset
63    #[cfg(feature = "arena")]
64    pub(super) ops_since_arena_reset: usize,
65}
66
67/// Multi-document session manager with built-in thread-safety
68pub struct EditorSessionManager {
69    #[cfg(feature = "multi-thread")]
70    inner: Arc<Mutex<EditorSessionManagerInner>>,
71    #[cfg(not(feature = "multi-thread"))]
72    inner: RefCell<EditorSessionManagerInner>,
73}
74
75// EditorSessionManager is cloneable when multi-thread feature is enabled
76#[cfg(feature = "multi-thread")]
77impl Clone for EditorSessionManager {
78    fn clone(&self) -> Self {
79        Self {
80            inner: self.inner.clone(),
81        }
82    }
83}
84
85// Note: EditorSessionManager does not implement Clone without multi-thread feature
86// This is intentional - cloning requires Arc<Mutex<T>> which needs multi-thread
87
88impl std::fmt::Debug for EditorSessionManager {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        #[cfg(feature = "multi-thread")]
91        {
92            let inner = self.inner.lock();
93            f.debug_struct("EditorSessionManager")
94                .field("config", &inner.config)
95                .field("active_session_id", &inner.active_session_id)
96                .field("sessions", &inner.sessions.keys().collect::<Vec<_>>())
97                .field("stats", &inner.stats)
98                .finish()
99        }
100        #[cfg(not(feature = "multi-thread"))]
101        {
102            let inner = self.inner.borrow();
103            f.debug_struct("EditorSessionManager")
104                .field("config", &inner.config)
105                .field("active_session_id", &inner.active_session_id)
106                .field("sessions", &inner.sessions.keys().collect::<Vec<_>>())
107                .field("stats", &inner.stats)
108                .finish()
109        }
110    }
111}
112
113impl EditorSessionManagerInner {
114    /// Create a new inner session manager
115    fn new(config: SessionConfig) -> Self {
116        Self {
117            config,
118            sessions: HashMap::new(),
119            active_session_id: None,
120            #[cfg(feature = "arena")]
121            shared_arena: Bump::new(),
122            #[cfg(feature = "plugins")]
123            extension_registry: None,
124            stats: SessionStats {
125                active_sessions: 0,
126                total_memory_usage: 0,
127                operations_since_cleanup: 0,
128                arena_resets: 0,
129            },
130            #[cfg(feature = "arena")]
131            ops_since_arena_reset: 0,
132        }
133    }
134}
135
136impl EditorSessionManager {
137    /// Helper method for accessing inner data mutably
138    #[cfg(feature = "multi-thread")]
139    pub(super) fn with_inner_mut<F, R>(&self, f: F) -> R
140    where
141        F: FnOnce(&mut EditorSessionManagerInner) -> R,
142    {
143        let mut inner = self.inner.lock();
144        f(&mut inner)
145    }
146
147    /// Helper method for accessing inner data immutably
148    #[cfg(feature = "multi-thread")]
149    pub(super) fn with_inner<F, R>(&self, f: F) -> R
150    where
151        F: FnOnce(&EditorSessionManagerInner) -> R,
152    {
153        let inner = self.inner.lock();
154        f(&inner)
155    }
156
157    /// Helper method for accessing inner data mutably
158    #[cfg(not(feature = "multi-thread"))]
159    pub(super) fn with_inner_mut<F, R>(&self, f: F) -> R
160    where
161        F: FnOnce(&mut EditorSessionManagerInner) -> R,
162    {
163        let mut inner = self.inner.borrow_mut();
164        f(&mut inner)
165    }
166
167    /// Helper method for accessing inner data immutably
168    #[cfg(not(feature = "multi-thread"))]
169    pub(super) fn with_inner<F, R>(&self, f: F) -> R
170    where
171        F: FnOnce(&EditorSessionManagerInner) -> R,
172    {
173        let inner = self.inner.borrow();
174        f(&inner)
175    }
176
177    /// Create a new session manager with custom configuration
178    pub fn with_config(config: SessionConfig) -> Self {
179        #[cfg(feature = "multi-thread")]
180        {
181            Self {
182                inner: Arc::new(Mutex::new(EditorSessionManagerInner::new(config))),
183            }
184        }
185        #[cfg(not(feature = "multi-thread"))]
186        {
187            Self {
188                inner: RefCell::new(EditorSessionManagerInner::new(config)),
189            }
190        }
191    }
192}