kcl_lib/engine/
conn_mock.rs

1//! Functions for setting up our WebSocket and WebRTC connections for communications with the
2//! engine.
3
4use std::{collections::HashMap, sync::Arc};
5
6use anyhow::Result;
7use indexmap::IndexMap;
8use kcmc::{
9    ok_response::OkModelingCmdResponse,
10    websocket::{
11        BatchResponse, ModelingBatch, OkWebSocketResponseData, SuccessWebSocketResponse, WebSocketRequest,
12        WebSocketResponse,
13    },
14};
15use kittycad_modeling_cmds::{self as kcmc};
16use tokio::sync::RwLock;
17use uuid::Uuid;
18
19use super::{EngineStats, ExecutionKind};
20use crate::{
21    errors::KclError,
22    exec::DefaultPlanes,
23    execution::{ArtifactCommand, IdGenerator},
24    SourceRange,
25};
26
27#[derive(Debug, Clone)]
28pub struct EngineConnection {
29    batch: Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>>,
30    batch_end: Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>>,
31    artifact_commands: Arc<RwLock<Vec<ArtifactCommand>>>,
32    execution_kind: Arc<RwLock<ExecutionKind>>,
33    /// The default planes for the scene.
34    default_planes: Arc<RwLock<Option<DefaultPlanes>>>,
35    stats: EngineStats,
36}
37
38impl EngineConnection {
39    pub async fn new() -> Result<EngineConnection> {
40        Ok(EngineConnection {
41            batch: Arc::new(RwLock::new(Vec::new())),
42            batch_end: Arc::new(RwLock::new(IndexMap::new())),
43            artifact_commands: Arc::new(RwLock::new(Vec::new())),
44            execution_kind: Default::default(),
45            default_planes: Default::default(),
46            stats: Default::default(),
47        })
48    }
49}
50
51#[async_trait::async_trait]
52impl crate::engine::EngineManager for EngineConnection {
53    fn batch(&self) -> Arc<RwLock<Vec<(WebSocketRequest, SourceRange)>>> {
54        self.batch.clone()
55    }
56
57    fn batch_end(&self) -> Arc<RwLock<IndexMap<uuid::Uuid, (WebSocketRequest, SourceRange)>>> {
58        self.batch_end.clone()
59    }
60
61    fn responses(&self) -> Arc<RwLock<IndexMap<Uuid, WebSocketResponse>>> {
62        Arc::new(RwLock::new(IndexMap::new()))
63    }
64
65    fn stats(&self) -> &EngineStats {
66        &self.stats
67    }
68
69    fn artifact_commands(&self) -> Arc<RwLock<Vec<ArtifactCommand>>> {
70        self.artifact_commands.clone()
71    }
72
73    async fn execution_kind(&self) -> ExecutionKind {
74        let guard = self.execution_kind.read().await;
75        *guard
76    }
77
78    async fn replace_execution_kind(&self, execution_kind: ExecutionKind) -> ExecutionKind {
79        let mut guard = self.execution_kind.write().await;
80        let original = *guard;
81        *guard = execution_kind;
82        original
83    }
84
85    fn get_default_planes(&self) -> Arc<RwLock<Option<DefaultPlanes>>> {
86        self.default_planes.clone()
87    }
88
89    async fn clear_scene_post_hook(
90        &self,
91        _id_generator: &mut IdGenerator,
92        _source_range: SourceRange,
93    ) -> Result<(), KclError> {
94        Ok(())
95    }
96
97    async fn inner_send_modeling_cmd(
98        &self,
99        id: uuid::Uuid,
100        _source_range: SourceRange,
101        cmd: WebSocketRequest,
102        _id_to_source_range: HashMap<Uuid, SourceRange>,
103    ) -> Result<WebSocketResponse, KclError> {
104        match cmd {
105            WebSocketRequest::ModelingCmdBatchReq(ModelingBatch {
106                ref requests,
107                batch_id: _,
108                responses: _,
109            }) => {
110                // Create the empty responses.
111                let mut responses = HashMap::with_capacity(requests.len());
112                for request in requests {
113                    responses.insert(
114                        request.cmd_id,
115                        BatchResponse::Success {
116                            response: OkModelingCmdResponse::Empty {},
117                        },
118                    );
119                }
120                Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
121                    request_id: Some(id),
122                    resp: OkWebSocketResponseData::ModelingBatch { responses },
123                    success: true,
124                }))
125            }
126            WebSocketRequest::ModelingCmdReq(_) => Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
127                request_id: Some(id),
128                resp: OkWebSocketResponseData::Modeling {
129                    modeling_response: OkModelingCmdResponse::Empty {},
130                },
131                success: true,
132            })),
133            _ => Ok(WebSocketResponse::Success(SuccessWebSocketResponse {
134                request_id: Some(id),
135                resp: OkWebSocketResponseData::Modeling {
136                    modeling_response: OkModelingCmdResponse::Empty {},
137                },
138                success: true,
139            })),
140        }
141    }
142
143    async fn close(&self) {}
144}