blockly_rust_compiler/
blockly_bridge.rs

1// Blockly Bridge - Integration between Blockly editor and Rust applications
2
3use serde::{Deserialize, Serialize};
4use std::fs;
5use std::path::Path;
6
7/// Load a genome from Blockly-generated JSON
8pub fn load_blockly_genome(path: &Path) -> Result<BlocklyGenome, Box<dyn std::error::Error>> {
9    let content = fs::read_to_string(path)?;
10    let genome: BlocklyGenome = serde_json::from_str(&content)?;
11    Ok(genome)
12}
13
14/// Save a genome to Blockly-compatible JSON
15pub fn save_blockly_genome(genome: &BlocklyGenome, path: &Path) -> Result<(), Box<dyn std::error::Error>> {
16    let json = serde_json::to_string_pretty(genome)?;
17    fs::write(path, json)?;
18    Ok(())
19}
20
21/// Blockly-compatible genome structure
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct BlocklyGenome {
24    pub name: String,
25    pub initial_mode: usize,
26    pub initial_orientation: Quaternion,
27    pub modes: Vec<BlocklyMode>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct BlocklyMode {
32    pub name: String,
33    pub default_name: String,
34    pub color: Color3,
35    pub cell_type: u32,
36    pub parent_make_adhesion: bool,
37    pub split_mass: f32,
38    pub split_interval: f32,
39    pub parent_split_direction: Vec2,
40    pub max_adhesions: u32,
41    pub min_adhesions: u32,
42    pub enable_parent_angle_snapping: bool,
43    pub max_splits: i32,
44    pub mode_a_after_splits: i32,
45    pub mode_b_after_splits: i32,
46    pub child_a: ChildSettings,
47    pub child_b: ChildSettings,
48    pub adhesion_settings: AdhesionSettings,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct ChildSettings {
53    pub mode_number: usize,
54    pub orientation: Quaternion,
55    pub keep_adhesion: bool,
56    pub enable_angle_snapping: bool,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct AdhesionSettings {
61    pub can_break: bool,
62    pub break_force: f32,
63    pub rest_length: f32,
64    pub linear_spring_stiffness: f32,
65    pub linear_spring_damping: f32,
66    pub orientation_spring_stiffness: f32,
67    pub orientation_spring_damping: f32,
68    pub max_angular_deviation: f32,
69    pub twist_constraint_stiffness: f32,
70    pub twist_constraint_damping: f32,
71    pub enable_twist_constraint: bool,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct Quaternion {
76    pub x: f32,
77    pub y: f32,
78    pub z: f32,
79    pub w: f32,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct Color3 {
84    pub x: f32,
85    pub y: f32,
86    pub z: f32,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct Vec2 {
91    pub x: f32,
92    pub y: f32,
93}
94
95/// Convert Blockly genome to application-specific internal format
96/// Note: Implement this when integrating with your genome system
97// impl BlocklyGenome {
98//     pub fn to_internal_genome(&self) -> YourGenomeType {
99//         // Convert Blockly format to internal genome format
100//         // This would integrate with your existing genome system
101//         todo!("Implement conversion to internal genome format")
102//     }
103// }
104
105/// WGSL shader validation and loading
106pub fn validate_wgsl_shader(source: &str) -> Result<(), String> {
107    // Basic validation - check for required elements
108    if !source.contains("@compute") {
109        return Err("Missing @compute attribute".to_string());
110    }
111    if !source.contains("@workgroup_size") {
112        return Err("Missing @workgroup_size attribute".to_string());
113    }
114    Ok(())
115}
116
117pub fn load_blockly_wgsl(path: &Path) -> Result<String, Box<dyn std::error::Error>> {
118    let source = fs::read_to_string(path)?;
119    validate_wgsl_shader(&source)?;
120    Ok(source)
121}
122
123#[cfg(test)]
124mod tests {
125    use super::*;
126
127    #[test]
128    fn test_genome_serialization() {
129        let genome = BlocklyGenome {
130            name: "Test Genome".to_string(),
131            initial_mode: 0,
132            initial_orientation: Quaternion { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
133            modes: vec![],
134        };
135
136        let json = serde_json::to_string(&genome).unwrap();
137        let deserialized: BlocklyGenome = serde_json::from_str(&json).unwrap();
138        
139        assert_eq!(genome.name, deserialized.name);
140        assert_eq!(genome.initial_mode, deserialized.initial_mode);
141    }
142
143    #[test]
144    fn test_wgsl_validation() {
145        let valid_shader = "@compute @workgroup_size(64) fn main() {}";
146        assert!(validate_wgsl_shader(valid_shader).is_ok());
147
148        let invalid_shader = "fn main() {}";
149        assert!(validate_wgsl_shader(invalid_shader).is_err());
150    }
151}