Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-platform/src/init.rs
1//! Granular initialization system for StratoUI
2//!
3//! This module provides fine-grained control over the initialization process,
4//! allowing developers to customize font loading, logging, and other aspects
5//! of the framework initialization.
6 
7use std::sync::{Arc, OnceLock, RwLock};
8use strato_core::{Result, StratoError};
9use strato_renderer::text::TextRenderer;
10 
11/// Global text renderer instance to avoid multiple cosmic_text initializations
12static GLOBAL_TEXT_RENDERER: OnceLock<Arc<RwLock<TextRenderer>>> = OnceLock::new();
13 
14/// Configuration for StratoUI initialization
15#[derive(Debug, Clone)]
16pub struct InitConfig {
17 /// Enable detailed logging during initialization
18 pub enable_logging: bool,
19 /// Skip problematic system fonts (like mstmc.ttf)
20 pub skip_problematic_fonts: bool,
21 /// Maximum number of font faces to load (None = unlimited)
22 pub max_font_faces: Option<usize>,
23 /// Custom font directories to search
24 pub custom_font_dirs: Vec<String>,
25 /// Preferred fonts to load first
26 pub preferred_fonts: Vec<String>,
27}
28 
29impl Default for InitConfig {
30 fn default() -> Self {
31 Self {
32 enable_logging: false,
33 skip_problematic_fonts: true,
34 max_font_faces: Some(50),
35 custom_font_dirs: Vec::new(),
36 preferred_fonts: vec![
37 "Segoe UI".to_string(),
38 "Arial".to_string(),
39 "Helvetica".to_string(),
40 ],
41 }
42 }
43}
44 
45/// Builder for step-by-step initialization
46pub struct InitBuilder {
47 config: InitConfig,
48 core_initialized: bool,
49 widgets_initialized: bool,
50 platform_initialized: bool,
51}
52 
53impl InitBuilder {
54 /// Create a new initialization builder
55 pub fn new() -> Self {
56 Self {
57 config: InitConfig::default(),
58 core_initialized: false,
59 widgets_initialized: false,
60 platform_initialized: false,
61 }
62 }
63 
64 /// Set custom configuration
65 pub fn with_config(mut self, config: InitConfig) -> Self {
66 self.config = config;
67 self
68 }
69 
70 /// Initialize only the core module
71 pub fn init_core(&mut self) -> Result<&mut Self> {
72 if self.core_initialized {
73 return Ok(self);
74 }
75 
76 // Initialize core first (which includes logging)
77 strato_core::init()?;
78 self.core_initialized = true;
79 
80 if self.config.enable_logging {
81 strato_core::strato_trace!(strato_core::logging::LogCategory::Core, "Core initialized");
82 }
83 
84 Ok(self)
85 }
86 
87 /// Initialize only the widgets module
88 pub fn init_widgets(&mut self) -> Result<&mut Self> {
89 if !self.core_initialized {
90 self.init_core()?;
91 }
92 
93 if self.widgets_initialized {
94 return Ok(self);
95 }
96 
97 if self.config.enable_logging {
98 strato_core::strato_trace!(
99 strato_core::logging::LogCategory::Core,
100 "Initializing widgets..."
101 );
102 }
103 
104 strato_widgets::init()?;
105 self.widgets_initialized = true;
106 
107 if self.config.enable_logging {
108 strato_core::strato_trace!(
109 strato_core::logging::LogCategory::Core,
110 "Widgets initialized"
111 );
112 }
113 
114 Ok(self)
115 }
116 
117 /// Initialize only the platform module with optimized font loading
118 pub fn init_platform(&mut self) -> Result<&mut Self> {
119 if !self.core_initialized {
120 self.init_core()?;
121 }
122 
123 if self.platform_initialized {
124 return Ok(self);
125 }
126 
127 if self.config.enable_logging {
128 strato_core::strato_trace!(
129 strato_core::logging::LogCategory::Platform,
130 "Initializing platform with font optimizations..."
131 );
132 }
133 
134 // Initialize platform with our custom configuration
135 crate::init().map_err(|e| {
136 strato_core::StratoError::platform(format!("Platform init failed: {}", e))
137 })?;
138 
139 // Initialize the global text renderer with optimizations
140 self.init_optimized_text_renderer()?;
141 
142 self.platform_initialized = true;
143 
144 if self.config.enable_logging {
145 strato_core::strato_trace!(
146 strato_core::logging::LogCategory::Platform,
147 "Platform initialized"
148 );
149 }
150 
151 Ok(self)
152 }
153 
154 /// Initialize all modules at once
155 pub fn init_all(&mut self) -> Result<()> {
156 self.init_core()?.init_widgets()?.init_platform()?;
157 Ok(())
158 }
159 
160 /// Initialize the optimized text renderer
161 fn init_optimized_text_renderer(&self) -> Result<()> {
162 if GLOBAL_TEXT_RENDERER.get().is_some() {
163 return Ok(()); // Already initialized
164 }
165 
166 // Create optimized text renderer
167 strato_core::strato_trace!(
168 strato_core::logging::LogCategory::Platform,
169 "Creating optimized TextRenderer"
170 );
171 let text_renderer = TextRenderer::new();
172 
173 GLOBAL_TEXT_RENDERER
174 .set(Arc::new(RwLock::new(text_renderer)))
175 .map_err(|_| StratoError::platform("Failed to set global text renderer".to_string()))?;
176 
177 Ok(())
178 }
179}
180 
181impl Default for InitBuilder {
182 fn default() -> Self {
183 Self::new()
184 }
185}
186 
187/// Get the global text renderer instance
188pub fn get_text_renderer() -> Option<Arc<RwLock<TextRenderer>>> {
189 GLOBAL_TEXT_RENDERER.get().cloned()
190}
191 
192/// Convenience function for full initialization with default config
193pub fn init_all() -> Result<()> {
194 InitBuilder::new().init_all()
195}
196 
197/// Convenience function for initialization with custom config
198pub fn init_with_config(config: InitConfig) -> Result<()> {
199 InitBuilder::new().with_config(config).init_all()
200}
201 
202/// Check if the framework is fully initialized
203pub fn is_initialized() -> bool {
204 GLOBAL_TEXT_RENDERER.get().is_some()
205}
206 
207#[cfg(test)]
208mod tests {
209 use super::*;
210 
211 #[test]
212 fn test_init_config_default() {
213 let config = InitConfig::default();
214 assert!(!config.enable_logging);
215 assert!(config.skip_problematic_fonts);
216 assert_eq!(config.max_font_faces, Some(50));
217 }
218 
219 #[test]
220 fn test_init_builder() {
221 let mut builder = InitBuilder::new();
222 assert!(!builder.core_initialized);
223 assert!(!builder.widgets_initialized);
224 assert!(!builder.platform_initialized);
225 }
226}
227