Skip to main content

v_shield/
lib.rs

1//! 🛡️ V-Shield - Platform Layer + Sync Primitives for Ry-Dit
2//!
3//! **V-Shield** provee:
4//!
5//! - 🎨 **Colores** constantes para RyDit (con o sin raylib)
6//! - 🔒 **Sync Primitives** multiplataforma (Mutex, RwLock, Barrier, Condvar)
7//! - 🖥️ **Platform Detection** (Linux, Windows, macOS, Android, iOS, WASM)
8//! - 🔄 **Platform Sync** para sincronización de renderizado
9//!
10//! # Features
11//!
12//! | Feature | Descripción | Dependencias |
13//! |---------|-------------|--------------|
14//! | `native` (default) | Sync nativo (std::sync) | Ninguna extra |
15//! | `wasm` | Sync para WASM | Ninguna extra |
16//! | `graphics` (default) | Colores raylib + window init | raylib |
17//! | `async-tokio` | Wrappers async | tokio (solo sync) |
18//! | `rt-linux` | Linux real-time | rtsc |
19//!
20//! # Ejemplo rápido
21//!
22//! ```rust
23//! use v_shield::sync::{Mutex, RwLock};
24//! use v_shield::platform::{current_platform, PlatformConfig};
25//! use v_shield::platform_sync::PlatformSync;
26//!
27//! // Platform detection
28//! let p = current_platform();
29//! println!("Running on: {}", p.name());
30//!
31//! // Config defaults
32//! let config = PlatformConfig::for_current();
33//!
34//! // Sync primitives
35//! let data = Mutex::new(vec![1, 2, 3]);
36//! let cache = RwLock::new(String::new());
37//!
38//! // Platform sync para renderizado
39//! let mut sync = PlatformSync::new();
40//! // sync.sync(); // al final de cada frame
41//! ```
42//!
43//! # Para Termux/Android
44//!
45//! Funciona sin cambios en Termux. Solo necesitas:
46//! ```bash
47//! pkg install clang libx11-dev libxcb-dev
48//! ```
49
50// ============================================================================
51// Platform Detection
52// ============================================================================
53pub mod platform;
54
55// ============================================================================
56// Platform Sync (renderizado)
57// ============================================================================
58pub mod platform_sync;
59
60// ============================================================================
61// Sync Primitives
62// ============================================================================
63pub mod sync;
64
65// ============================================================================
66// Graphics (colores + window) - solo con feature "graphics"
67// ============================================================================
68#[cfg(feature = "graphics")]
69mod graphics {
70    pub use raylib;
71    pub use raylib::consts::KeyboardKey::*;
72    pub use raylib::prelude::*;
73
74    use std::str::FromStr;
75
76    // Definir colores manualmente (raylib nobuild no incluye colors::prelude)
77    pub const RED: Color = Color {
78        r: 230, g: 41, b: 55, a: 255,
79    };
80    pub const GREEN: Color = Color {
81        r: 117, g: 203, b: 100, a: 255,
82    };
83    pub const BLUE: Color = Color {
84        r: 51, g: 122, b: 206, a: 255,
85    };
86    pub const YELLOW: Color = Color {
87        r: 253, g: 249, b: 0, a: 255,
88    };
89    pub const WHITE: Color = Color {
90        r: 255, g: 255, b: 255, a: 255,
91    };
92    pub const BLACK: Color = Color {
93        r: 0, g: 0, b: 0, a: 255,
94    };
95    pub const CYAN: Color = Color {
96        r: 0, g: 255, b: 255, a: 255,
97    };
98    pub const MAGENTA: Color = Color {
99        r: 255, g: 0, b: 255, a: 255,
100    };
101    pub const ORANGE: Color = Color {
102        r: 255, g: 165, b: 0, a: 255,
103    };
104    pub const PINK: Color = Color {
105        r: 255, g: 192, b: 203, a: 255,
106    };
107    pub const PURPLE: Color = Color {
108        r: 128, g: 0, b: 128, a: 255,
109    };
110    pub const BROWN: Color = Color {
111        r: 165, g: 42, b: 42, a: 255,
112    };
113    pub const GRAY: Color = Color {
114        r: 128, g: 128, b: 128, a: 255,
115    };
116    pub const LIME: Color = Color {
117        r: 0, g: 255, b: 0, a: 255,
118    };
119    pub const NAVY: Color = Color {
120        r: 0, g: 0, b: 128, a: 255,
121    };
122    pub const OLIVE: Color = Color {
123        r: 128, g: 128, b: 0, a: 255,
124    };
125    pub const TEAL: Color = Color {
126        r: 0, g: 128, b: 128, a: 255,
127    };
128    pub const MAROON: Color = Color {
129        r: 128, g: 0, b: 0, a: 255,
130    };
131
132    /// Colores básicos para RyDit
133    #[derive(Debug, Clone, Copy, PartialEq)]
134    pub enum ColorRyDit {
135        Rojo, Verde, Azul, Amarillo, Blanco, Negro,
136        Cyan, Magenta, Naranja, Rosa, Morado, Cafe,
137        Gris, Lima, AzulOscuro, Oliva, Turquesa, Vino,
138    }
139
140    impl ColorRyDit {
141        pub fn to_color(&self) -> Color {
142            match self {
143                Self::Rojo => RED, Self::Verde => GREEN, Self::Azul => BLUE,
144                Self::Amarillo => YELLOW, Self::Blanco => WHITE, Self::Negro => BLACK,
145                Self::Cyan => CYAN, Self::Magenta => MAGENTA, Self::Naranja => ORANGE,
146                Self::Rosa => PINK, Self::Morado => PURPLE, Self::Cafe => BROWN,
147                Self::Gris => GRAY, Self::Lima => LIME, Self::AzulOscuro => NAVY,
148                Self::Oliva => OLIVE, Self::Turquesa => TEAL, Self::Vino => MAROON,
149            }
150        }
151    }
152
153    impl FromStr for ColorRyDit {
154        type Err = ();
155        fn from_str(s: &str) -> Result<Self, Self::Err> {
156            match s.to_lowercase().as_str() {
157                "rojo" | "red" => Ok(Self::Rojo),
158                "verde" | "green" => Ok(Self::Verde),
159                "azul" | "blue" => Ok(Self::Azul),
160                "amarillo" | "yellow" => Ok(Self::Amarillo),
161                "blanco" | "white" => Ok(Self::Blanco),
162                "negro" | "black" => Ok(Self::Negro),
163                "cyan" | "celeste" => Ok(Self::Cyan),
164                "magenta" | "fucsia" => Ok(Self::Magenta),
165                "naranja" | "orange" => Ok(Self::Naranja),
166                "rosa" | "pink" => Ok(Self::Rosa),
167                "morado" | "purple" | "violeta" => Ok(Self::Morado),
168                "cafe" | "brown" | "marron" => Ok(Self::Cafe),
169                "gris" | "gray" | "grey" => Ok(Self::Gris),
170                "lima" | "lime" => Ok(Self::Lima),
171                "azuloscuro" | "navy" | "azul oscuro" => Ok(Self::AzulOscuro),
172                "oliva" | "olive" => Ok(Self::Oliva),
173                "turquesa" | "teal" => Ok(Self::Turquesa),
174                "vino" | "maroon" | "granate" => Ok(Self::Vino),
175                _ => Ok(Self::Negro),
176            }
177        }
178    }
179
180    /// Inicializar ventana
181    pub fn init_window(titulo: &str, w: i32, h: i32) -> (raylib::RaylibHandle, raylib::RaylibThread) {
182        raylib::init().size(w, h).title(titulo).build()
183    }
184}
185
186#[cfg(feature = "graphics")]
187pub use graphics::*;
188
189// Re-exports convenience
190pub use platform::{current_platform, Platform, PlatformConfig};
191pub use platform_sync::{PlatformSync, PlatformSyncMode};
192pub use sync::{Mutex, RwLock};
193
194/// Versión del crate
195pub const VERSION: &str = env!("CARGO_PKG_VERSION");
196
197// ============================================================================
198// Tests de integración
199// ============================================================================
200#[cfg(test)]
201mod tests {
202    use super::*;
203
204    #[test]
205    fn test_version() {
206        assert_eq!(VERSION, "0.2.0");
207    }
208
209    #[test]
210    fn test_exports() {
211        // Verificar que los re-exports funcionan
212        let _ = current_platform();
213        let _ = PlatformConfig::for_current();
214        let _ = PlatformSync::new();
215        let _ = Mutex::new(0);
216        let _ = RwLock::new(0);
217    }
218
219    // Tests de colores (solo con feature graphics)
220    #[cfg(feature = "graphics")]
221    mod color_tests {
222        use super::*;
223        use std::str::FromStr;
224
225        #[test]
226        fn test_color_from_str() {
227            assert_eq!(ColorRyDit::from_str("rojo").unwrap(), ColorRyDit::Rojo);
228            assert_eq!(ColorRyDit::from_str("RED").unwrap(), ColorRyDit::Rojo);
229            assert_eq!(ColorRyDit::from_str("verde").unwrap(), ColorRyDit::Verde);
230            assert_eq!(ColorRyDit::from_str("azul").unwrap(), ColorRyDit::Azul);
231            assert_eq!(ColorRyDit::from_str("blanco").unwrap(), ColorRyDit::Blanco);
232            assert_eq!(ColorRyDit::from_str("otro").unwrap(), ColorRyDit::Negro);
233            assert_eq!(ColorRyDit::from_str("cyan").unwrap(), ColorRyDit::Cyan);
234            assert_eq!(ColorRyDit::from_str("magenta").unwrap(), ColorRyDit::Magenta);
235        }
236
237        #[test]
238        fn test_colores_constantes() {
239            assert_eq!(RED.r, 230); assert_eq!(RED.g, 41); assert_eq!(RED.b, 55);
240            assert_eq!(GREEN.r, 117); assert_eq!(GREEN.g, 203); assert_eq!(GREEN.b, 100);
241            assert_eq!(BLUE.r, 51); assert_eq!(BLUE.g, 122); assert_eq!(BLUE.b, 206);
242            assert_eq!(WHITE.r, 255); assert_eq!(WHITE.g, 255); assert_eq!(WHITE.b, 255);
243            assert_eq!(BLACK.r, 0); assert_eq!(BLACK.g, 0); assert_eq!(BLACK.b, 0);
244        }
245
246        #[test]
247        fn test_color_to_color() {
248            assert_eq!(ColorRyDit::Rojo.to_color().r, 230);
249            assert_eq!(ColorRyDit::Verde.to_color().r, 117);
250            assert_eq!(ColorRyDit::Azul.to_color().r, 51);
251        }
252
253        #[test]
254        fn test_color_desconocido_retorna_negro() {
255            assert_eq!(ColorRyDit::from_str("color_raro").unwrap(), ColorRyDit::Negro);
256            assert_eq!(ColorRyDit::from_str("").unwrap(), ColorRyDit::Negro);
257        }
258    }
259}