Kcl updates for snapshot stuff for cli (#350)

* updates for snapshot file

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2023-08-29 19:13:30 -07:00
committed by GitHub
parent 2b1a556b81
commit 743ea1af4d
3 changed files with 31 additions and 64 deletions

View File

@ -947,7 +947,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.2"
version = "0.1.3"
dependencies = [
"anyhow",
"bson",
@ -975,9 +975,9 @@ dependencies = [
[[package]]
name = "kittycad"
version = "0.2.21"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfeb41d39852f5755cd3f2d1c06059839f268cbc5d0577c2d6a667c6ad5abdcf"
checksum = "0247f7acbe36141604ad02b796b596fe0392fb86dd82550eb2f4855b2a493344"
dependencies = [
"anyhow",
"base64 0.21.2",

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
license = "MIT"

View File

@ -15,6 +15,7 @@ pub struct EngineConnection {
tcp_write: futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<reqwest::Upgraded>, WsMsg>,
tcp_read_handle: tokio::task::JoinHandle<Result<()>>,
export_notifier: Arc<tokio::sync::Notify>,
snapshot_notifier: Arc<tokio::sync::Notify>,
}
impl Drop for EngineConnection {
@ -41,7 +42,7 @@ impl TcpRead {
}
impl EngineConnection {
pub async fn new(ws: reqwest::Upgraded, export_dir: &str) -> Result<EngineConnection> {
pub async fn new(ws: reqwest::Upgraded, export_dir: &str, snapshot_file: &str) -> Result<EngineConnection> {
// Make sure the export directory exists and that it is a directory.
let export_dir = std::path::Path::new(export_dir).to_owned();
if !export_dir.exists() {
@ -66,6 +67,11 @@ impl EngineConnection {
let export_notifier = Arc::new(tokio::sync::Notify::new());
let export_notifier_clone = export_notifier.clone();
let snapshot_notifier = Arc::new(tokio::sync::Notify::new());
let snapshot_notifier_clone = snapshot_notifier.clone();
let snapshot_file = snapshot_file.to_owned();
let tcp_read_handle = tokio::spawn(async move {
// Get Websocket messages from API server
loop {
@ -90,7 +96,20 @@ impl EngineConnection {
OkWebSocketResponseData::TrickleIce { candidate } => {
println!("got trickle ice: {:?}", candidate);
}
OkWebSocketResponseData::Modeling { .. } => {}
OkWebSocketResponseData::Modeling { modeling_response } => {
if let kittycad::types::OkModelingCmdResponse::TakeSnapshot { data } =
modeling_response
{
if snapshot_file.is_empty() {
println!("Got snapshot, but no snapshot file specified.");
continue;
}
// Save the snapshot locally.
std::fs::write(&snapshot_file, data.contents)?;
snapshot_notifier.notify_one();
}
}
OkWebSocketResponseData::Export { files } => {
// Save the files to our export directory.
for file in files {
@ -118,13 +137,18 @@ impl EngineConnection {
tcp_write,
tcp_read_handle,
export_notifier: export_notifier_clone,
snapshot_notifier: snapshot_notifier_clone,
})
}
pub async fn wait_for_files(&self) {
pub async fn wait_for_export(&self) {
self.export_notifier.notified().await;
}
pub async fn wait_for_snapshot(&self) {
self.snapshot_notifier.notified().await;
}
pub async fn tcp_send(&mut self, msg: WebSocketRequest) -> Result<()> {
let msg = serde_json::to_string(&msg)?;
self.tcp_write.send(WsMsg::Text(msg)).await?;
@ -149,60 +173,3 @@ impl EngineConnection {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::executor::{execute, BodyType, ProgramMemory, SourceRange};
pub async fn parse_execute_export(code: &str) -> Result<()> {
let tokens = crate::tokeniser::lexer(code);
let export_dir_str = "/tmp/";
let program = crate::parser::abstract_syntax_tree(&tokens)?;
let mut mem: ProgramMemory = Default::default();
let mut engine = EngineConnection::new(
"wss://api.dev.kittycad.io/ws/modeling/commands?webrtc=false",
std::env::var("KITTYCAD_API_TOKEN").unwrap().as_str(),
"modeling-app-tests",
export_dir_str,
)
.await?;
let _ = execute(program, &mut mem, BodyType::Root, &mut engine)?;
// Send an export request to the engine.
engine.send_modeling_cmd(
uuid::Uuid::new_v4(),
SourceRange::default(),
kittycad::types::ModelingCmd::Export {
entity_ids: vec![],
format: kittycad::types::OutputFormat::Gltf {
presentation: kittycad::types::Presentation::Pretty,
storage: kittycad::types::Storage::Embedded,
},
},
)?;
engine.wait_for_files().await;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_export_file() {
let ast = r#"const part001 = startSketchAt([-0.01, -0.06])
|> line([0, 20], %)
|> line([5, 0], %)
|> line([-10, 5], %)
|> close(%)
|> extrude(4, %)
show(part001)"#;
parse_execute_export(ast).await.unwrap();
// Ensure we have a file called "part001.gltf" in the export directory.
let export_dir = std::path::Path::new("/tmp/");
let export_file = export_dir.join("part001.gltf");
assert!(export_file.exists());
// Make sure the file is not empty.
assert!(export_file.metadata().unwrap().len() != 0);
}
}