make stdlib functions async (#672)
* wip Signed-off-by: Jess Frazelle <github@jessfraz.com> updates Signed-off-by: Jess Frazelle <github@jessfraz.com> updates Signed-off-by: Jess Frazelle <github@jessfraz.com> fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> closer Signed-off-by: Jess Frazelle <github@jessfraz.com> fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * closer Signed-off-by: Jess Frazelle <github@jessfraz.com> * closer Signed-off-by: Jess Frazelle <github@jessfraz.com> * compiles Signed-off-by: Jess Frazelle <github@jessfraz.com> * connection Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix wasm Signed-off-by: Jess Frazelle <github@jessfraz.com> * timeout Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove the drop Signed-off-by: Jess Frazelle <github@jessfraz.com> * drop handle Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -5,6 +5,9 @@ import {
|
|||||||
EngineCommand,
|
EngineCommand,
|
||||||
} from '../lang/std/engineConnection'
|
} from '../lang/std/engineConnection'
|
||||||
import { SourceRange } from 'lang/executor'
|
import { SourceRange } from 'lang/executor'
|
||||||
|
import { Models } from '@kittycad/lib'
|
||||||
|
|
||||||
|
type WebSocketResponse = Models['OkWebSocketResponseData_type']
|
||||||
|
|
||||||
class MockEngineCommandManager {
|
class MockEngineCommandManager {
|
||||||
constructor(mockParams: {
|
constructor(mockParams: {
|
||||||
@ -23,7 +26,13 @@ class MockEngineCommandManager {
|
|||||||
range: SourceRange
|
range: SourceRange
|
||||||
command: EngineCommand
|
command: EngineCommand
|
||||||
}): Promise<any> {
|
}): Promise<any> {
|
||||||
return Promise.resolve()
|
const response: WebSocketResponse = {
|
||||||
|
type: 'modeling',
|
||||||
|
data: {
|
||||||
|
modeling_response: { type: 'empty' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return Promise.resolve(JSON.stringify(response))
|
||||||
}
|
}
|
||||||
sendModelingCommandFromWasm(
|
sendModelingCommandFromWasm(
|
||||||
id: string,
|
id: string,
|
||||||
|
14
src/wasm-lib/Cargo.lock
generated
14
src/wasm-lib/Cargo.lock
generated
@ -148,6 +148,17 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-recursion"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.37",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.73"
|
version = "0.1.73"
|
||||||
@ -1376,9 +1387,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.1.30"
|
version = "0.1.31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"async-recursion",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bson",
|
"bson",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -79,13 +79,6 @@ fn do_stdlib_inner(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ast.sig.asyncness.is_some() {
|
|
||||||
errors.push(Error::new_spanned(
|
|
||||||
&ast.sig.fn_token,
|
|
||||||
"stdlib functions must not be async",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ast.sig.unsafety.is_some() {
|
if ast.sig.unsafety.is_some() {
|
||||||
errors.push(Error::new_spanned(
|
errors.push(Error::new_spanned(
|
||||||
&ast.sig.unsafety,
|
&ast.sig.unsafety,
|
||||||
@ -118,6 +111,7 @@ fn do_stdlib_inner(
|
|||||||
let fn_name = &ast.sig.ident;
|
let fn_name = &ast.sig.ident;
|
||||||
let fn_name_str = fn_name.to_string().replace("inner_", "");
|
let fn_name_str = fn_name.to_string().replace("inner_", "");
|
||||||
let fn_name_ident = format_ident!("{}", fn_name_str);
|
let fn_name_ident = format_ident!("{}", fn_name_str);
|
||||||
|
let boxed_fn_name_ident = format_ident!("boxed_{}", fn_name_str);
|
||||||
let _visibility = &ast.vis;
|
let _visibility = &ast.vis;
|
||||||
|
|
||||||
let (summary_text, description_text) = extract_doc_from_attrs(&ast.attrs);
|
let (summary_text, description_text) = extract_doc_from_attrs(&ast.attrs);
|
||||||
@ -204,7 +198,10 @@ fn do_stdlib_inner(
|
|||||||
syn::FnArg::Typed(pat) => pat.ty.as_ref().into_token_stream(),
|
syn::FnArg::Typed(pat) => pat.ty.as_ref().into_token_stream(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty_string = ty.to_string().replace('&', "").replace("mut", "").replace(' ', "");
|
let mut ty_string = ty.to_string().replace('&', "").replace("mut", "").replace(' ', "");
|
||||||
|
if ty_string.starts_with("Args") {
|
||||||
|
ty_string = "Args".to_string();
|
||||||
|
}
|
||||||
let ty_string = ty_string.trim().to_string();
|
let ty_string = ty_string.trim().to_string();
|
||||||
let ty_ident = if ty_string.starts_with("Vec<") {
|
let ty_ident = if ty_string.starts_with("Vec<") {
|
||||||
let ty_string = ty_string.trim_start_matches("Vec<").trim_end_matches('>');
|
let ty_string = ty_string.trim_start_matches("Vec<").trim_end_matches('>');
|
||||||
@ -305,6 +302,14 @@ fn do_stdlib_inner(
|
|||||||
#description_doc_comment
|
#description_doc_comment
|
||||||
#const_struct
|
#const_struct
|
||||||
|
|
||||||
|
fn #boxed_fn_name_ident(
|
||||||
|
args: crate::std::Args,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<dyn std::future::Future<Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>>>,
|
||||||
|
> {
|
||||||
|
Box::pin(#fn_name_ident(args))
|
||||||
|
}
|
||||||
|
|
||||||
impl #docs_crate::StdLibFn for #name_ident
|
impl #docs_crate::StdLibFn for #name_ident
|
||||||
{
|
{
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
@ -348,7 +353,7 @@ fn do_stdlib_inner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||||
#fn_name_ident
|
#boxed_fn_name_ident
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn #docs_crate::StdLibFn> {
|
fn clone_box(&self) -> Box<dyn #docs_crate::StdLibFn> {
|
||||||
|
@ -7,6 +7,18 @@ pub(crate) struct Show {}
|
|||||||
#[allow(non_upper_case_globals, missing_docs)]
|
#[allow(non_upper_case_globals, missing_docs)]
|
||||||
#[doc = "Std lib function: show"]
|
#[doc = "Std lib function: show"]
|
||||||
pub(crate) const Show: Show = Show {};
|
pub(crate) const Show: Show = Show {};
|
||||||
|
fn boxed_show(
|
||||||
|
args: crate::std::Args,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<
|
||||||
|
dyn std::future::Future<
|
||||||
|
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
> {
|
||||||
|
Box::pin(show(args))
|
||||||
|
}
|
||||||
|
|
||||||
impl crate::docs::StdLibFn for Show {
|
impl crate::docs::StdLibFn for Show {
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
"show".to_string()
|
"show".to_string()
|
||||||
@ -57,7 +69,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||||
show
|
boxed_show
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||||
|
@ -7,6 +7,18 @@ pub(crate) struct LineTo {}
|
|||||||
#[allow(non_upper_case_globals, missing_docs)]
|
#[allow(non_upper_case_globals, missing_docs)]
|
||||||
#[doc = "Std lib function: lineTo"]
|
#[doc = "Std lib function: lineTo"]
|
||||||
pub(crate) const LineTo: LineTo = LineTo {};
|
pub(crate) const LineTo: LineTo = LineTo {};
|
||||||
|
fn boxed_line_to(
|
||||||
|
args: crate::std::Args,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<
|
||||||
|
dyn std::future::Future<
|
||||||
|
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
> {
|
||||||
|
Box::pin(line_to(args))
|
||||||
|
}
|
||||||
|
|
||||||
impl crate::docs::StdLibFn for LineTo {
|
impl crate::docs::StdLibFn for LineTo {
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
"lineTo".to_string()
|
"lineTo".to_string()
|
||||||
@ -65,7 +77,7 @@ impl crate::docs::StdLibFn for LineTo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||||
line_to
|
boxed_line_to
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||||
|
@ -7,6 +7,18 @@ pub(crate) struct Min {}
|
|||||||
#[allow(non_upper_case_globals, missing_docs)]
|
#[allow(non_upper_case_globals, missing_docs)]
|
||||||
#[doc = "Std lib function: min"]
|
#[doc = "Std lib function: min"]
|
||||||
pub(crate) const Min: Min = Min {};
|
pub(crate) const Min: Min = Min {};
|
||||||
|
fn boxed_min(
|
||||||
|
args: crate::std::Args,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<
|
||||||
|
dyn std::future::Future<
|
||||||
|
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
> {
|
||||||
|
Box::pin(min(args))
|
||||||
|
}
|
||||||
|
|
||||||
impl crate::docs::StdLibFn for Min {
|
impl crate::docs::StdLibFn for Min {
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
"min".to_string()
|
"min".to_string()
|
||||||
@ -57,7 +69,7 @@ impl crate::docs::StdLibFn for Min {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||||
min
|
boxed_min
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||||
|
@ -7,6 +7,18 @@ pub(crate) struct Show {}
|
|||||||
#[allow(non_upper_case_globals, missing_docs)]
|
#[allow(non_upper_case_globals, missing_docs)]
|
||||||
#[doc = "Std lib function: show"]
|
#[doc = "Std lib function: show"]
|
||||||
pub(crate) const Show: Show = Show {};
|
pub(crate) const Show: Show = Show {};
|
||||||
|
fn boxed_show(
|
||||||
|
args: crate::std::Args,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<
|
||||||
|
dyn std::future::Future<
|
||||||
|
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
> {
|
||||||
|
Box::pin(show(args))
|
||||||
|
}
|
||||||
|
|
||||||
impl crate::docs::StdLibFn for Show {
|
impl crate::docs::StdLibFn for Show {
|
||||||
fn name(&self) -> String {
|
fn name(&self) -> String {
|
||||||
"show".to_string()
|
"show".to_string()
|
||||||
@ -52,7 +64,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||||
show
|
boxed_show
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language"
|
description = "KittyCAD Language"
|
||||||
version = "0.1.30"
|
version = "0.1.31"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
@ -9,6 +9,7 @@ license = "MIT"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||||
|
async-recursion = "1.0.5"
|
||||||
async-trait = "0.1.73"
|
async-trait = "0.1.73"
|
||||||
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
clap = { version = "4.4.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
||||||
dashmap = "5.5.3"
|
dashmap = "5.5.3"
|
||||||
|
@ -71,7 +71,7 @@ pub async fn modify_ast_for_sketch(
|
|||||||
|
|
||||||
// Let's get the path info.
|
// Let's get the path info.
|
||||||
let resp = engine
|
let resp = engine
|
||||||
.send_modeling_cmd_get_response(
|
.send_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
SourceRange::default(),
|
SourceRange::default(),
|
||||||
ModelingCmd::PathGetInfo { path_id: sketch_id },
|
ModelingCmd::PathGetInfo { path_id: sketch_id },
|
||||||
@ -88,47 +88,6 @@ pub async fn modify_ast_for_sketch(
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* // Let's try to get the children of the sketch.
|
|
||||||
let resp = engine
|
|
||||||
.send_modeling_cmd_get_response(
|
|
||||||
uuid::Uuid::new_v4(),
|
|
||||||
SourceRange::default(),
|
|
||||||
ModelingCmd::EntityGetAllChildUuids { entity_id: sketch_id },
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let kittycad::types::OkWebSocketResponseData::Modeling {
|
|
||||||
modeling_response: kittycad::types::OkModelingCmdResponse::EntityGetAllChildUuids { data: children_info },
|
|
||||||
} = &resp
|
|
||||||
else {
|
|
||||||
return Err(KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Get child info response was not as expected: {:?}", resp),
|
|
||||||
source_ranges: vec![SourceRange::default()],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("children_info: {:#?}", children_info);
|
|
||||||
|
|
||||||
// Let's try to get the parent id.
|
|
||||||
let resp = engine
|
|
||||||
.send_modeling_cmd_get_response(
|
|
||||||
uuid::Uuid::new_v4(),
|
|
||||||
SourceRange::default(),
|
|
||||||
ModelingCmd::EntityGetParentId { entity_id: sketch_id },
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let kittycad::types::OkWebSocketResponseData::Modeling {
|
|
||||||
modeling_response: kittycad::types::OkModelingCmdResponse::EntityGetParentId { data: parent_info },
|
|
||||||
} = &resp
|
|
||||||
else {
|
|
||||||
return Err(KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Get parent id response was not as expected: {:?}", resp),
|
|
||||||
source_ranges: vec![SourceRange::default()],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("parent_info: {:#?}", parent_info);*/
|
|
||||||
|
|
||||||
// Now let's get the control points for all the segments.
|
// Now let's get the control points for all the segments.
|
||||||
// TODO: We should probably await all these at once so we aren't going one by one.
|
// TODO: We should probably await all these at once so we aren't going one by one.
|
||||||
// But I guess this is fine for now.
|
// But I guess this is fine for now.
|
||||||
@ -136,7 +95,7 @@ pub async fn modify_ast_for_sketch(
|
|||||||
let mut control_points = Vec::new();
|
let mut control_points = Vec::new();
|
||||||
for segment in &path_info.segments {
|
for segment in &path_info.segments {
|
||||||
if let Some(command_id) = &segment.command_id {
|
if let Some(command_id) = &segment.command_id {
|
||||||
let h = engine.send_modeling_cmd_get_response(
|
let h = engine.send_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
SourceRange::default(),
|
SourceRange::default(),
|
||||||
ModelingCmd::CurveGetControlPoints { curve_id: *command_id },
|
ModelingCmd::CurveGetControlPoints { curve_id: *command_id },
|
||||||
|
@ -571,11 +571,12 @@ impl BinaryPart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_result(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
pub async fn get_result(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
// stop the execution of the pipe.
|
// stop the execution of the pipe.
|
||||||
@ -590,11 +591,13 @@ impl BinaryPart {
|
|||||||
Ok(value.clone())
|
Ok(value.clone())
|
||||||
}
|
}
|
||||||
BinaryPart::BinaryExpression(binary_expression) => {
|
BinaryPart::BinaryExpression(binary_expression) => {
|
||||||
binary_expression.get_result(memory, &mut new_pipe_info, engine)
|
binary_expression.get_result(memory, &mut new_pipe_info, engine).await
|
||||||
|
}
|
||||||
|
BinaryPart::CallExpression(call_expression) => {
|
||||||
|
call_expression.execute(memory, &mut new_pipe_info, engine).await
|
||||||
}
|
}
|
||||||
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, &mut new_pipe_info, engine),
|
|
||||||
BinaryPart::UnaryExpression(unary_expression) => {
|
BinaryPart::UnaryExpression(unary_expression) => {
|
||||||
unary_expression.get_result(memory, &mut new_pipe_info, engine)
|
unary_expression.get_result(memory, &mut new_pipe_info, engine).await
|
||||||
}
|
}
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(memory),
|
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(memory),
|
||||||
}
|
}
|
||||||
@ -810,11 +813,12 @@ impl CallExpression {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
pub async fn execute(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
let fn_name = self.callee.name.clone();
|
let fn_name = self.callee.name.clone();
|
||||||
|
|
||||||
@ -828,7 +832,7 @@ impl CallExpression {
|
|||||||
value.clone()
|
value.clone()
|
||||||
}
|
}
|
||||||
Value::BinaryExpression(binary_expression) => {
|
Value::BinaryExpression(binary_expression) => {
|
||||||
binary_expression.get_result(memory, pipe_info, engine)?
|
binary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
@ -836,11 +840,15 @@ impl CallExpression {
|
|||||||
// THIS IS IMPORTANT.
|
// THIS IS IMPORTANT.
|
||||||
let mut new_pipe_info = pipe_info.clone();
|
let mut new_pipe_info = pipe_info.clone();
|
||||||
new_pipe_info.is_in_pipe = false;
|
new_pipe_info.is_in_pipe = false;
|
||||||
call_expression.execute(memory, &mut new_pipe_info, engine)?
|
call_expression.execute(memory, &mut new_pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
Value::UnaryExpression(unary_expression) => {
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
|
unary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine)?,
|
}
|
||||||
|
Value::ObjectExpression(object_expression) => {
|
||||||
|
object_expression.execute(memory, pipe_info, engine).await?
|
||||||
|
}
|
||||||
|
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine).await?,
|
||||||
Value::PipeExpression(pipe_expression) => {
|
Value::PipeExpression(pipe_expression) => {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("PipeExpression not implemented here: {:?}", pipe_expression),
|
message: format!("PipeExpression not implemented here: {:?}", pipe_expression),
|
||||||
@ -877,20 +885,22 @@ impl CallExpression {
|
|||||||
fn_name, source_range, fn_args
|
fn_name, source_range, fn_args
|
||||||
);*/
|
);*/
|
||||||
// Attempt to call the function.
|
// Attempt to call the function.
|
||||||
let mut args = crate::std::Args::new(fn_args, self.into(), engine);
|
let args = crate::std::Args::new(fn_args, self.into(), engine.clone());
|
||||||
let result = func.std_lib_fn()(&mut args)?;
|
let result = func.std_lib_fn()(args).await?;
|
||||||
if pipe_info.is_in_pipe {
|
if pipe_info.is_in_pipe {
|
||||||
pipe_info.index += 1;
|
pipe_info.index += 1;
|
||||||
pipe_info.previous_results.push(result);
|
pipe_info.previous_results.push(result);
|
||||||
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), engine)
|
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), engine).await
|
||||||
} else {
|
} else {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Function::InMemory => {
|
Function::InMemory => {
|
||||||
let mem = memory.clone();
|
let func = memory.get(&fn_name, self.into())?;
|
||||||
let func = mem.get(&fn_name, self.into())?;
|
let result = func
|
||||||
let result = func.call_fn(&fn_args, &mem, engine)?.ok_or_else(|| {
|
.call_fn(fn_args, memory.clone(), engine.clone())
|
||||||
|
.await?
|
||||||
|
.ok_or_else(|| {
|
||||||
KclError::UndefinedValue(KclErrorDetails {
|
KclError::UndefinedValue(KclErrorDetails {
|
||||||
message: format!("Result of function {} is undefined", fn_name),
|
message: format!("Result of function {} is undefined", fn_name),
|
||||||
source_ranges: vec![self.into()],
|
source_ranges: vec![self.into()],
|
||||||
@ -903,7 +913,7 @@ impl CallExpression {
|
|||||||
pipe_info.index += 1;
|
pipe_info.index += 1;
|
||||||
pipe_info.previous_results.push(result);
|
pipe_info.previous_results.push(result);
|
||||||
|
|
||||||
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), engine)
|
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), engine).await
|
||||||
} else {
|
} else {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@ -1424,11 +1434,12 @@ impl ArrayExpression {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
pub async fn execute(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
let mut results = Vec::with_capacity(self.elements.len());
|
let mut results = Vec::with_capacity(self.elements.len());
|
||||||
|
|
||||||
@ -1440,7 +1451,7 @@ impl ArrayExpression {
|
|||||||
value.clone()
|
value.clone()
|
||||||
}
|
}
|
||||||
Value::BinaryExpression(binary_expression) => {
|
Value::BinaryExpression(binary_expression) => {
|
||||||
binary_expression.get_result(memory, pipe_info, engine)?
|
binary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
@ -1448,12 +1459,16 @@ impl ArrayExpression {
|
|||||||
// THIS IS IMPORTANT.
|
// THIS IS IMPORTANT.
|
||||||
let mut new_pipe_info = pipe_info.clone();
|
let mut new_pipe_info = pipe_info.clone();
|
||||||
new_pipe_info.is_in_pipe = false;
|
new_pipe_info.is_in_pipe = false;
|
||||||
call_expression.execute(memory, &mut new_pipe_info, engine)?
|
call_expression.execute(memory, &mut new_pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
Value::UnaryExpression(unary_expression) => {
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
|
unary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine)?,
|
}
|
||||||
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, engine)?,
|
Value::ObjectExpression(object_expression) => {
|
||||||
|
object_expression.execute(memory, pipe_info, engine).await?
|
||||||
|
}
|
||||||
|
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine).await?,
|
||||||
|
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, engine).await?,
|
||||||
Value::PipeSubstitution(pipe_substitution) => {
|
Value::PipeSubstitution(pipe_substitution) => {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
|
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
|
||||||
@ -1569,11 +1584,12 @@ impl ObjectExpression {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
pub async fn execute(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
let mut object = Map::new();
|
let mut object = Map::new();
|
||||||
for property in &self.properties {
|
for property in &self.properties {
|
||||||
@ -1584,7 +1600,7 @@ impl ObjectExpression {
|
|||||||
value.clone()
|
value.clone()
|
||||||
}
|
}
|
||||||
Value::BinaryExpression(binary_expression) => {
|
Value::BinaryExpression(binary_expression) => {
|
||||||
binary_expression.get_result(memory, pipe_info, engine)?
|
binary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
@ -1592,12 +1608,16 @@ impl ObjectExpression {
|
|||||||
// THIS IS IMPORTANT.
|
// THIS IS IMPORTANT.
|
||||||
let mut new_pipe_info = pipe_info.clone();
|
let mut new_pipe_info = pipe_info.clone();
|
||||||
new_pipe_info.is_in_pipe = false;
|
new_pipe_info.is_in_pipe = false;
|
||||||
call_expression.execute(memory, &mut new_pipe_info, engine)?
|
call_expression.execute(memory, &mut new_pipe_info, engine).await?
|
||||||
}
|
}
|
||||||
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, engine)?,
|
Value::UnaryExpression(unary_expression) => {
|
||||||
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, engine)?,
|
unary_expression.get_result(memory, pipe_info, engine).await?
|
||||||
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine)?,
|
}
|
||||||
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, engine)?,
|
Value::ObjectExpression(object_expression) => {
|
||||||
|
object_expression.execute(memory, pipe_info, engine).await?
|
||||||
|
}
|
||||||
|
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, engine).await?,
|
||||||
|
Value::PipeExpression(pipe_expression) => pipe_expression.get_result(memory, pipe_info, engine).await?,
|
||||||
Value::PipeSubstitution(pipe_substitution) => {
|
Value::PipeSubstitution(pipe_substitution) => {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
|
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
|
||||||
@ -2005,11 +2025,12 @@ impl BinaryExpression {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_result(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
pub async fn get_result(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
// stop the execution of the pipe.
|
// stop the execution of the pipe.
|
||||||
@ -2019,11 +2040,13 @@ impl BinaryExpression {
|
|||||||
|
|
||||||
let left_json_value = self
|
let left_json_value = self
|
||||||
.left
|
.left
|
||||||
.get_result(memory, &mut new_pipe_info, engine)?
|
.get_result(memory, &mut new_pipe_info, engine)
|
||||||
|
.await?
|
||||||
.get_json_value()?;
|
.get_json_value()?;
|
||||||
let right_json_value = self
|
let right_json_value = self
|
||||||
.right
|
.right
|
||||||
.get_result(memory, &mut new_pipe_info, engine)?
|
.get_result(memory, &mut new_pipe_info, engine)
|
||||||
|
.await?
|
||||||
.get_json_value()?;
|
.get_json_value()?;
|
||||||
|
|
||||||
// First check if we are doing string concatenation.
|
// First check if we are doing string concatenation.
|
||||||
@ -2173,11 +2196,11 @@ impl UnaryExpression {
|
|||||||
format!("{}{}", &self.operator, self.argument.recast(options, 0))
|
format!("{}{}", &self.operator, self.argument.recast(options, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_result(
|
pub async fn get_result(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
|
||||||
// stop the execution of the pipe.
|
// stop the execution of the pipe.
|
||||||
@ -2188,7 +2211,8 @@ impl UnaryExpression {
|
|||||||
let num = parse_json_number_as_f64(
|
let num = parse_json_number_as_f64(
|
||||||
&self
|
&self
|
||||||
.argument
|
.argument
|
||||||
.get_result(memory, &mut new_pipe_info, engine)?
|
.get_result(memory, &mut new_pipe_info, engine)
|
||||||
|
.await?
|
||||||
.get_json_value()?,
|
.get_json_value()?,
|
||||||
self.into(),
|
self.into(),
|
||||||
)?;
|
)?;
|
||||||
@ -2310,16 +2334,16 @@ impl PipeExpression {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_result(
|
pub async fn get_result(
|
||||||
&self,
|
&self,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
// Reset the previous results.
|
// Reset the previous results.
|
||||||
pipe_info.previous_results = vec![];
|
pipe_info.previous_results = vec![];
|
||||||
pipe_info.index = 0;
|
pipe_info.index = 0;
|
||||||
execute_pipe_body(memory, &self.body, pipe_info, self.into(), engine)
|
execute_pipe_body(memory, &self.body, pipe_info, self.into(), engine).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rename all identifiers that have the old name to the new given name.
|
/// Rename all identifiers that have the old name to the new given name.
|
||||||
@ -2330,12 +2354,13 @@ impl PipeExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_pipe_body(
|
#[async_recursion::async_recursion(?Send)]
|
||||||
|
async fn execute_pipe_body(
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
body: &[Value],
|
body: &[Value],
|
||||||
pipe_info: &mut PipeInfo,
|
pipe_info: &mut PipeInfo,
|
||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<MemoryItem, KclError> {
|
) -> Result<MemoryItem, KclError> {
|
||||||
if pipe_info.index == body.len() {
|
if pipe_info.index == body.len() {
|
||||||
pipe_info.is_in_pipe = false;
|
pipe_info.is_in_pipe = false;
|
||||||
@ -2360,15 +2385,15 @@ fn execute_pipe_body(
|
|||||||
|
|
||||||
match expression {
|
match expression {
|
||||||
Value::BinaryExpression(binary_expression) => {
|
Value::BinaryExpression(binary_expression) => {
|
||||||
let result = binary_expression.get_result(memory, pipe_info, engine)?;
|
let result = binary_expression.get_result(memory, pipe_info, engine).await?;
|
||||||
pipe_info.previous_results.push(result);
|
pipe_info.previous_results.push(result);
|
||||||
pipe_info.index += 1;
|
pipe_info.index += 1;
|
||||||
execute_pipe_body(memory, body, pipe_info, source_range, engine)
|
execute_pipe_body(memory, body, pipe_info, source_range, engine).await
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
pipe_info.is_in_pipe = true;
|
pipe_info.is_in_pipe = true;
|
||||||
pipe_info.body = body.to_vec();
|
pipe_info.body = body.to_vec();
|
||||||
call_expression.execute(memory, pipe_info, engine)
|
call_expression.execute(memory, pipe_info, engine).await
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Return an error this should not happen.
|
// Return an error this should not happen.
|
||||||
|
@ -17,17 +17,11 @@ use crate::{
|
|||||||
|
|
||||||
type WebSocketTcpWrite = futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<reqwest::Upgraded>, WsMsg>;
|
type WebSocketTcpWrite = futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<reqwest::Upgraded>, WsMsg>;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)] // for the TcpReadHandle
|
||||||
pub struct EngineConnection {
|
pub struct EngineConnection {
|
||||||
engine_req_tx: mpsc::Sender<ToEngineReq>,
|
engine_req_tx: mpsc::Sender<ToEngineReq>,
|
||||||
tcp_read_handle: Arc<tokio::task::JoinHandle<Result<()>>>,
|
|
||||||
responses: Arc<DashMap<uuid::Uuid, WebSocketResponse>>,
|
responses: Arc<DashMap<uuid::Uuid, WebSocketResponse>>,
|
||||||
}
|
tcp_read_handle: Arc<TcpReadHandle>,
|
||||||
|
|
||||||
impl Drop for EngineConnection {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// Drop the read handle.
|
|
||||||
self.tcp_read_handle.abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TcpRead {
|
pub struct TcpRead {
|
||||||
@ -48,6 +42,18 @@ impl TcpRead {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TcpReadHandle {
|
||||||
|
handle: Arc<tokio::task::JoinHandle<Result<()>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TcpReadHandle {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Drop the read handle.
|
||||||
|
self.handle.abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Requests to send to the engine, and a way to await a response.
|
/// Requests to send to the engine, and a way to await a response.
|
||||||
struct ToEngineReq {
|
struct ToEngineReq {
|
||||||
/// The request to send
|
/// The request to send
|
||||||
@ -114,7 +120,9 @@ impl EngineConnection {
|
|||||||
|
|
||||||
Ok(EngineConnection {
|
Ok(EngineConnection {
|
||||||
engine_req_tx,
|
engine_req_tx,
|
||||||
tcp_read_handle: Arc::new(tcp_read_handle),
|
tcp_read_handle: Arc::new(TcpReadHandle {
|
||||||
|
handle: Arc::new(tcp_read_handle),
|
||||||
|
}),
|
||||||
responses,
|
responses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -122,20 +130,7 @@ impl EngineConnection {
|
|||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl EngineManager for EngineConnection {
|
impl EngineManager for EngineConnection {
|
||||||
/// Send a modeling command.
|
async fn send_modeling_cmd(
|
||||||
/// Do not wait for the response message.
|
|
||||||
fn send_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: crate::executor::SourceRange,
|
|
||||||
cmd: kittycad::types::ModelingCmd,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
futures::executor::block_on(self.send_modeling_cmd_get_response(id, source_range, cmd))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Send a modeling command and wait for the response message.
|
|
||||||
async fn send_modeling_cmd_get_response(
|
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
source_range: crate::executor::SourceRange,
|
source_range: crate::executor::SourceRange,
|
||||||
@ -146,7 +141,10 @@ impl EngineManager for EngineConnection {
|
|||||||
// Send the request to the engine, via the actor.
|
// Send the request to the engine, via the actor.
|
||||||
self.engine_req_tx
|
self.engine_req_tx
|
||||||
.send(ToEngineReq {
|
.send(ToEngineReq {
|
||||||
req: WebSocketRequest::ModelingCmdReq { cmd, cmd_id: id },
|
req: WebSocketRequest::ModelingCmdReq {
|
||||||
|
cmd: cmd.clone(),
|
||||||
|
cmd_id: id,
|
||||||
|
},
|
||||||
request_sent: tx,
|
request_sent: tx,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
@ -173,8 +171,10 @@ impl EngineManager for EngineConnection {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Wait for the response.
|
// Wait for the response.
|
||||||
loop {
|
let current_time = std::time::Instant::now();
|
||||||
if let Some(resp) = self.responses.get(&id) {
|
while current_time.elapsed().as_secs() < 60 {
|
||||||
|
// We pop off the responses to cleanup our mappings.
|
||||||
|
if let Some((_, resp)) = self.responses.remove(&id) {
|
||||||
return if let Some(data) = &resp.resp {
|
return if let Some(data) = &resp.resp {
|
||||||
Ok(data.clone())
|
Ok(data.clone())
|
||||||
} else {
|
} else {
|
||||||
@ -185,5 +185,10 @@ impl EngineManager for EngineConnection {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Err(KclError::Engine(KclErrorDetails {
|
||||||
|
message: format!("Modeling command timed out `{}`: {:?}", id, cmd),
|
||||||
|
source_ranges: vec![source_range],
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,14 @@ impl EngineConnection {
|
|||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl crate::engine::EngineManager for EngineConnection {
|
impl crate::engine::EngineManager for EngineConnection {
|
||||||
fn send_modeling_cmd(
|
async fn send_modeling_cmd(
|
||||||
&self,
|
|
||||||
_id: uuid::Uuid,
|
|
||||||
_source_range: crate::executor::SourceRange,
|
|
||||||
_cmd: kittycad::types::ModelingCmd,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_modeling_cmd_get_response(
|
|
||||||
&self,
|
&self,
|
||||||
_id: uuid::Uuid,
|
_id: uuid::Uuid,
|
||||||
_source_range: crate::executor::SourceRange,
|
_source_range: crate::executor::SourceRange,
|
||||||
_cmd: kittycad::types::ModelingCmd,
|
_cmd: kittycad::types::ModelingCmd,
|
||||||
) -> Result<OkWebSocketResponseData, KclError> {
|
) -> Result<OkWebSocketResponseData, KclError> {
|
||||||
todo!()
|
Ok(OkWebSocketResponseData::Modeling {
|
||||||
|
modeling_response: kittycad::types::OkModelingCmdResponse::Empty {},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Functions for setting up our WebSocket and WebRTC connections for communications with the
|
//! Functions for setting up our WebSocket and WebRTC connections for communications with the
|
||||||
//! engine.
|
//! engine.
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use kittycad::types::WebSocketRequest;
|
use kittycad::types::WebSocketRequest;
|
||||||
@ -23,43 +24,20 @@ extern "C" {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EngineConnection {
|
pub struct EngineConnection {
|
||||||
manager: EngineCommandManager,
|
manager: Arc<EngineCommandManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EngineConnection {
|
impl EngineConnection {
|
||||||
pub async fn new(manager: EngineCommandManager) -> Result<EngineConnection, JsValue> {
|
pub async fn new(manager: EngineCommandManager) -> Result<EngineConnection, JsValue> {
|
||||||
Ok(EngineConnection { manager })
|
Ok(EngineConnection {
|
||||||
|
manager: Arc::new(manager),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl crate::engine::EngineManager for EngineConnection {
|
impl crate::engine::EngineManager for EngineConnection {
|
||||||
fn send_modeling_cmd(
|
async fn send_modeling_cmd(
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: crate::executor::SourceRange,
|
|
||||||
cmd: kittycad::types::ModelingCmd,
|
|
||||||
) -> Result<(), KclError> {
|
|
||||||
let source_range_str = serde_json::to_string(&source_range).map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Failed to serialize source range: {:?}", e),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let ws_msg = WebSocketRequest::ModelingCmdReq { cmd, cmd_id: id };
|
|
||||||
let cmd_str = serde_json::to_string(&ws_msg).map_err(|e| {
|
|
||||||
KclError::Engine(KclErrorDetails {
|
|
||||||
message: format!("Failed to serialize modeling command: {:?}", e),
|
|
||||||
source_ranges: vec![source_range],
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let _ = self
|
|
||||||
.manager
|
|
||||||
.sendModelingCommandFromWasm(id.to_string(), source_range_str, cmd_str);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_modeling_cmd_get_response(
|
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
source_range: crate::executor::SourceRange,
|
source_range: crate::executor::SourceRange,
|
||||||
|
@ -33,17 +33,8 @@ pub use conn_mock::EngineConnection;
|
|||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait EngineManager: Clone {
|
pub trait EngineManager: Clone {
|
||||||
/// Send a modeling command.
|
|
||||||
/// Do not wait for the response message.
|
|
||||||
fn send_modeling_cmd(
|
|
||||||
&self,
|
|
||||||
id: uuid::Uuid,
|
|
||||||
source_range: crate::executor::SourceRange,
|
|
||||||
cmd: kittycad::types::ModelingCmd,
|
|
||||||
) -> Result<(), crate::errors::KclError>;
|
|
||||||
|
|
||||||
/// Send a modeling command and wait for the response message.
|
/// Send a modeling command and wait for the response message.
|
||||||
async fn send_modeling_cmd_get_response(
|
async fn send_modeling_cmd(
|
||||||
&self,
|
&self,
|
||||||
id: uuid::Uuid,
|
id: uuid::Uuid,
|
||||||
source_range: crate::executor::SourceRange,
|
source_range: crate::executor::SourceRange,
|
||||||
|
@ -104,7 +104,7 @@ pub enum MemoryItem {
|
|||||||
SketchGroup(Box<SketchGroup>),
|
SketchGroup(Box<SketchGroup>),
|
||||||
ExtrudeGroup(Box<ExtrudeGroup>),
|
ExtrudeGroup(Box<ExtrudeGroup>),
|
||||||
#[ts(skip)]
|
#[ts(skip)]
|
||||||
ExtrudeTransform(ExtrudeTransform),
|
ExtrudeTransform(Box<ExtrudeTransform>),
|
||||||
#[ts(skip)]
|
#[ts(skip)]
|
||||||
Function {
|
Function {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
@ -134,13 +134,28 @@ pub struct ExtrudeTransform {
|
|||||||
pub meta: Vec<Metadata>,
|
pub meta: Vec<Metadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type MemoryFunction = fn(
|
pub type MemoryFunction =
|
||||||
s: &[MemoryItem],
|
fn(
|
||||||
memory: &ProgramMemory,
|
s: Vec<MemoryItem>,
|
||||||
expression: &FunctionExpression,
|
memory: ProgramMemory,
|
||||||
metadata: &[Metadata],
|
expression: Box<FunctionExpression>,
|
||||||
engine: &mut EngineConnection,
|
metadata: Vec<Metadata>,
|
||||||
) -> Result<Option<ProgramReturn>, KclError>;
|
engine: EngineConnection,
|
||||||
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>>>>;
|
||||||
|
|
||||||
|
fn force_memory_function<
|
||||||
|
F: Fn(
|
||||||
|
Vec<MemoryItem>,
|
||||||
|
ProgramMemory,
|
||||||
|
Box<FunctionExpression>,
|
||||||
|
Vec<Metadata>,
|
||||||
|
EngineConnection,
|
||||||
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<ProgramReturn>, KclError>>>>,
|
||||||
|
>(
|
||||||
|
f: F,
|
||||||
|
) -> F {
|
||||||
|
f
|
||||||
|
}
|
||||||
|
|
||||||
impl From<MemoryItem> for Vec<SourceRange> {
|
impl From<MemoryItem> for Vec<SourceRange> {
|
||||||
fn from(item: MemoryItem) -> Self {
|
fn from(item: MemoryItem) -> Self {
|
||||||
@ -168,24 +183,24 @@ impl MemoryItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_fn(
|
pub async fn call_fn(
|
||||||
&self,
|
&self,
|
||||||
args: &[MemoryItem],
|
args: Vec<MemoryItem>,
|
||||||
memory: &ProgramMemory,
|
memory: ProgramMemory,
|
||||||
engine: &mut EngineConnection,
|
engine: EngineConnection,
|
||||||
) -> Result<Option<ProgramReturn>, KclError> {
|
) -> Result<Option<ProgramReturn>, KclError> {
|
||||||
if let MemoryItem::Function { func, expression, meta } = self {
|
if let MemoryItem::Function { func, expression, meta } = &self {
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func(args, memory, expression, meta, engine)
|
func(args, memory, expression.clone(), meta.clone(), engine).await
|
||||||
} else {
|
} else {
|
||||||
Err(KclError::Semantic(KclErrorDetails {
|
Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("Not a function: {:?}", self),
|
message: format!("Not a function: {:?}", expression),
|
||||||
source_ranges: vec![],
|
source_ranges: vec![],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(KclError::Semantic(KclErrorDetails {
|
Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("not a function: {:?}", self),
|
message: "not a in memory function".to_string(),
|
||||||
source_ranges: vec![],
|
source_ranges: vec![],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -579,11 +594,11 @@ impl Default for PipeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a AST's program.
|
/// Execute a AST's program.
|
||||||
pub fn execute(
|
pub async fn execute(
|
||||||
program: crate::ast::types::Program,
|
program: crate::ast::types::Program,
|
||||||
memory: &mut ProgramMemory,
|
memory: &mut ProgramMemory,
|
||||||
options: BodyType,
|
options: BodyType,
|
||||||
engine: &mut EngineConnection,
|
engine: &EngineConnection,
|
||||||
) -> Result<ProgramMemory, KclError> {
|
) -> Result<ProgramMemory, KclError> {
|
||||||
let mut pipe_info = PipeInfo::default();
|
let mut pipe_info = PipeInfo::default();
|
||||||
|
|
||||||
@ -602,7 +617,7 @@ pub fn execute(
|
|||||||
args.push(memory_item.clone());
|
args.push(memory_item.clone());
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expr) => {
|
Value::CallExpression(call_expr) => {
|
||||||
let result = call_expr.execute(memory, &mut pipe_info, engine)?;
|
let result = call_expr.execute(memory, &mut pipe_info, engine).await?;
|
||||||
args.push(result);
|
args.push(result);
|
||||||
}
|
}
|
||||||
// We do nothing for the rest.
|
// We do nothing for the rest.
|
||||||
@ -620,7 +635,7 @@ pub fn execute(
|
|||||||
|
|
||||||
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
|
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
|
||||||
} else if let Some(func) = memory.clone().root.get(&fn_name) {
|
} else if let Some(func) = memory.clone().root.get(&fn_name) {
|
||||||
let result = func.call_fn(&args, memory, engine)?;
|
let result = func.call_fn(args.clone(), memory.clone(), engine.clone()).await?;
|
||||||
|
|
||||||
memory.return_ = result;
|
memory.return_ = result;
|
||||||
} else {
|
} else {
|
||||||
@ -646,22 +661,27 @@ pub fn execute(
|
|||||||
memory.add(&var_name, value.clone(), source_range)?;
|
memory.add(&var_name, value.clone(), source_range)?;
|
||||||
}
|
}
|
||||||
Value::BinaryExpression(binary_expression) => {
|
Value::BinaryExpression(binary_expression) => {
|
||||||
let result = binary_expression.get_result(memory, &mut pipe_info, engine)?;
|
let result = binary_expression.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::FunctionExpression(function_expression) => {
|
Value::FunctionExpression(function_expression) => {
|
||||||
memory.add(
|
let mem_func = force_memory_function(
|
||||||
&var_name,
|
|args: Vec<MemoryItem>,
|
||||||
MemoryItem::Function{
|
memory: ProgramMemory,
|
||||||
expression: function_expression.clone(),
|
function_expression: Box<FunctionExpression>,
|
||||||
meta: vec![metadata],
|
_metadata: Vec<Metadata>,
|
||||||
func: Some(|args: &[MemoryItem], memory: &ProgramMemory, function_expression: &FunctionExpression, _metadata: &[Metadata], engine: &mut EngineConnection| -> Result<Option<ProgramReturn>, KclError> {
|
engine: EngineConnection| {
|
||||||
|
Box::pin(async move {
|
||||||
let mut fn_memory = memory.clone();
|
let mut fn_memory = memory.clone();
|
||||||
|
|
||||||
if args.len() != function_expression.params.len() {
|
if args.len() != function_expression.params.len() {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: format!("Expected {} arguments, got {}", function_expression.params.len(), args.len()),
|
message: format!(
|
||||||
source_ranges: vec![function_expression.into()],
|
"Expected {} arguments, got {}",
|
||||||
|
function_expression.params.len(),
|
||||||
|
args.len()
|
||||||
|
),
|
||||||
|
source_ranges: vec![(&function_expression).into()],
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,20 +694,34 @@ pub fn execute(
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = execute(function_expression.body.clone(), &mut fn_memory, BodyType::Block, engine)?;
|
let result = execute(
|
||||||
|
function_expression.body.clone(),
|
||||||
|
&mut fn_memory,
|
||||||
|
BodyType::Block,
|
||||||
|
&engine,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(result.return_)
|
Ok(result.return_)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
memory.add(
|
||||||
|
&var_name,
|
||||||
|
MemoryItem::Function {
|
||||||
|
expression: function_expression.clone(),
|
||||||
|
meta: vec![metadata],
|
||||||
|
func: Some(mem_func),
|
||||||
|
},
|
||||||
source_range,
|
source_range,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expression) => {
|
Value::CallExpression(call_expression) => {
|
||||||
let result = call_expression.execute(memory, &mut pipe_info, engine)?;
|
let result = call_expression.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::PipeExpression(pipe_expression) => {
|
Value::PipeExpression(pipe_expression) => {
|
||||||
let result = pipe_expression.get_result(memory, &mut pipe_info, engine)?;
|
let result = pipe_expression.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::PipeSubstitution(pipe_substitution) => {
|
Value::PipeSubstitution(pipe_substitution) => {
|
||||||
@ -700,11 +734,11 @@ pub fn execute(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Value::ArrayExpression(array_expression) => {
|
Value::ArrayExpression(array_expression) => {
|
||||||
let result = array_expression.execute(memory, &mut pipe_info, engine)?;
|
let result = array_expression.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::ObjectExpression(object_expression) => {
|
Value::ObjectExpression(object_expression) => {
|
||||||
let result = object_expression.execute(memory, &mut pipe_info, engine)?;
|
let result = object_expression.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::MemberExpression(member_expression) => {
|
Value::MemberExpression(member_expression) => {
|
||||||
@ -712,7 +746,7 @@ pub fn execute(
|
|||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
Value::UnaryExpression(unary_expression) => {
|
Value::UnaryExpression(unary_expression) => {
|
||||||
let result = unary_expression.get_result(memory, &mut pipe_info, engine)?;
|
let result = unary_expression.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.add(&var_name, result, source_range)?;
|
memory.add(&var_name, result, source_range)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -720,11 +754,11 @@ pub fn execute(
|
|||||||
}
|
}
|
||||||
BodyItem::ReturnStatement(return_statement) => match &return_statement.argument {
|
BodyItem::ReturnStatement(return_statement) => match &return_statement.argument {
|
||||||
Value::BinaryExpression(bin_expr) => {
|
Value::BinaryExpression(bin_expr) => {
|
||||||
let result = bin_expr.get_result(memory, &mut pipe_info, engine)?;
|
let result = bin_expr.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::UnaryExpression(unary_expr) => {
|
Value::UnaryExpression(unary_expr) => {
|
||||||
let result = unary_expr.get_result(memory, &mut pipe_info, engine)?;
|
let result = unary_expr.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::Identifier(identifier) => {
|
Value::Identifier(identifier) => {
|
||||||
@ -735,15 +769,15 @@ pub fn execute(
|
|||||||
memory.return_ = Some(ProgramReturn::Value(literal.into()));
|
memory.return_ = Some(ProgramReturn::Value(literal.into()));
|
||||||
}
|
}
|
||||||
Value::ArrayExpression(array_expr) => {
|
Value::ArrayExpression(array_expr) => {
|
||||||
let result = array_expr.execute(memory, &mut pipe_info, engine)?;
|
let result = array_expr.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::ObjectExpression(obj_expr) => {
|
Value::ObjectExpression(obj_expr) => {
|
||||||
let result = obj_expr.execute(memory, &mut pipe_info, engine)?;
|
let result = obj_expr.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::CallExpression(call_expr) => {
|
Value::CallExpression(call_expr) => {
|
||||||
let result = call_expr.execute(memory, &mut pipe_info, engine)?;
|
let result = call_expr.execute(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::MemberExpression(member_expr) => {
|
Value::MemberExpression(member_expr) => {
|
||||||
@ -751,7 +785,7 @@ pub fn execute(
|
|||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::PipeExpression(pipe_expr) => {
|
Value::PipeExpression(pipe_expr) => {
|
||||||
let result = pipe_expr.get_result(memory, &mut pipe_info, engine)?;
|
let result = pipe_expr.get_result(memory, &mut pipe_info, engine).await?;
|
||||||
memory.return_ = Some(ProgramReturn::Value(result));
|
memory.return_ = Some(ProgramReturn::Value(result));
|
||||||
}
|
}
|
||||||
Value::PipeSubstitution(_) => {}
|
Value::PipeSubstitution(_) => {}
|
||||||
@ -774,8 +808,8 @@ mod tests {
|
|||||||
let parser = crate::parser::Parser::new(tokens);
|
let parser = crate::parser::Parser::new(tokens);
|
||||||
let program = parser.ast()?;
|
let program = parser.ast()?;
|
||||||
let mut mem: ProgramMemory = Default::default();
|
let mut mem: ProgramMemory = Default::default();
|
||||||
let mut engine = EngineConnection::new().await?;
|
let engine = EngineConnection::new().await?;
|
||||||
let memory = execute(program, &mut mem, BodyType::Root, &mut engine)?;
|
let memory = execute(program, &mut mem, BodyType::Root, &engine).await?;
|
||||||
|
|
||||||
Ok(memory)
|
Ok(memory)
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Extrudes by a given amount.
|
/// Extrudes by a given amount.
|
||||||
pub fn extrude(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn extrude(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (length, sketch_group) = args.get_number_sketch_group()?;
|
let (length, sketch_group) = args.get_number_sketch_group()?;
|
||||||
|
|
||||||
let result = inner_extrude(length, sketch_group, args)?;
|
let result = inner_extrude(length, sketch_group, args).await?;
|
||||||
|
|
||||||
Ok(MemoryItem::ExtrudeGroup(result))
|
Ok(MemoryItem::ExtrudeGroup(result))
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ pub fn extrude(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "extrude"
|
name = "extrude"
|
||||||
}]
|
}]
|
||||||
fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<ExtrudeGroup>, KclError> {
|
async fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<ExtrudeGroup>, KclError> {
|
||||||
let id = uuid::Uuid::new_v4();
|
let id = uuid::Uuid::new_v4();
|
||||||
|
|
||||||
let cmd = kittycad::types::ModelingCmd::Extrude {
|
let cmd = kittycad::types::ModelingCmd::Extrude {
|
||||||
@ -31,7 +31,7 @@ fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -
|
|||||||
distance: length,
|
distance: length,
|
||||||
cap: true,
|
cap: true,
|
||||||
};
|
};
|
||||||
args.send_modeling_cmd(id, cmd)?;
|
args.send_modeling_cmd(id, cmd).await?;
|
||||||
|
|
||||||
Ok(Box::new(ExtrudeGroup {
|
Ok(Box::new(ExtrudeGroup {
|
||||||
id,
|
id,
|
||||||
@ -46,7 +46,7 @@ fn inner_extrude(length: f64, sketch_group: Box<SketchGroup>, args: &mut Args) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the extrude wall transform.
|
/// Returns the extrude wall transform.
|
||||||
pub fn get_extrude_wall_transform(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn get_extrude_wall_transform(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (surface_name, extrude_group) = args.get_path_name_extrude_group()?;
|
let (surface_name, extrude_group) = args.get_path_name_extrude_group()?;
|
||||||
let result = inner_get_extrude_wall_transform(&surface_name, *extrude_group, args)?;
|
let result = inner_get_extrude_wall_transform(&surface_name, *extrude_group, args)?;
|
||||||
Ok(MemoryItem::ExtrudeTransform(result))
|
Ok(MemoryItem::ExtrudeTransform(result))
|
||||||
@ -59,8 +59,8 @@ pub fn get_extrude_wall_transform(args: &mut Args) -> Result<MemoryItem, KclErro
|
|||||||
fn inner_get_extrude_wall_transform(
|
fn inner_get_extrude_wall_transform(
|
||||||
surface_name: &str,
|
surface_name: &str,
|
||||||
extrude_group: ExtrudeGroup,
|
extrude_group: ExtrudeGroup,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<ExtrudeTransform, KclError> {
|
) -> Result<Box<ExtrudeTransform>, KclError> {
|
||||||
let surface = extrude_group.get_path_by_name(surface_name).ok_or_else(|| {
|
let surface = extrude_group.get_path_by_name(surface_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
message: format!(
|
message: format!(
|
||||||
@ -71,9 +71,9 @@ fn inner_get_extrude_wall_transform(
|
|||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(ExtrudeTransform {
|
Ok(Box::new(ExtrudeTransform {
|
||||||
position: surface.get_position(),
|
position: surface.get_position(),
|
||||||
rotation: surface.get_rotation(),
|
rotation: surface.get_rotation(),
|
||||||
meta: extrude_group.meta,
|
meta: extrude_group.meta,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Computes the cosine of a number (in radians).
|
/// Computes the cosine of a number (in radians).
|
||||||
pub fn cos(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn cos(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_cos(num)?;
|
let result = inner_cos(num)?;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ fn inner_cos(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the sine of a number (in radians).
|
/// Computes the sine of a number (in radians).
|
||||||
pub fn sin(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn sin(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_sin(num)?;
|
let result = inner_sin(num)?;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ fn inner_sin(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the tangent of a number (in radians).
|
/// Computes the tangent of a number (in radians).
|
||||||
pub fn tan(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn tan(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_tan(num)?;
|
let result = inner_tan(num)?;
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ fn inner_tan(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value of `pi`. Archimedes’ constant (π).
|
/// Return the value of `pi`. Archimedes’ constant (π).
|
||||||
pub fn pi(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn pi(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let result = inner_pi()?;
|
let result = inner_pi()?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
@ -74,7 +74,7 @@ fn inner_pi() -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the square root of a number.
|
/// Computes the square root of a number.
|
||||||
pub fn sqrt(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn sqrt(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_sqrt(num)?;
|
let result = inner_sqrt(num)?;
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ fn inner_sqrt(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the absolute value of a number.
|
/// Computes the absolute value of a number.
|
||||||
pub fn abs(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn abs(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_abs(num)?;
|
let result = inner_abs(num)?;
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ fn inner_abs(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the largest integer less than or equal to a number.
|
/// Computes the largest integer less than or equal to a number.
|
||||||
pub fn floor(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn floor(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_floor(num)?;
|
let result = inner_floor(num)?;
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ fn inner_floor(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the smallest integer greater than or equal to a number.
|
/// Computes the smallest integer greater than or equal to a number.
|
||||||
pub fn ceil(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn ceil(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_ceil(num)?;
|
let result = inner_ceil(num)?;
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ fn inner_ceil(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the minimum of the given arguments.
|
/// Computes the minimum of the given arguments.
|
||||||
pub fn min(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn min(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let nums = args.get_number_array()?;
|
let nums = args.get_number_array()?;
|
||||||
let result = inner_min(nums);
|
let result = inner_min(nums);
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ fn inner_min(args: Vec<f64>) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the maximum of the given arguments.
|
/// Computes the maximum of the given arguments.
|
||||||
pub fn max(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn max(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let nums = args.get_number_array()?;
|
let nums = args.get_number_array()?;
|
||||||
let result = inner_max(nums);
|
let result = inner_max(nums);
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ fn inner_max(args: Vec<f64>) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the number to a power.
|
/// Computes the number to a power.
|
||||||
pub fn pow(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn pow(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let nums = args.get_number_array()?;
|
let nums = args.get_number_array()?;
|
||||||
if nums.len() > 2 {
|
if nums.len() > 2 {
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
@ -214,7 +214,7 @@ fn inner_pow(num: f64, pow: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the arccosine of a number (in radians).
|
/// Computes the arccosine of a number (in radians).
|
||||||
pub fn acos(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn acos(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_acos(num)?;
|
let result = inner_acos(num)?;
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ fn inner_acos(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the arcsine of a number (in radians).
|
/// Computes the arcsine of a number (in radians).
|
||||||
pub fn asin(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn asin(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_asin(num)?;
|
let result = inner_asin(num)?;
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ fn inner_asin(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the arctangent of a number (in radians).
|
/// Computes the arctangent of a number (in radians).
|
||||||
pub fn atan(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn atan(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_atan(num)?;
|
let result = inner_atan(num)?;
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ fn inner_atan(num: f64) -> Result<f64, KclError> {
|
|||||||
/// The result might not be correctly rounded owing to implementation
|
/// The result might not be correctly rounded owing to implementation
|
||||||
/// details; `log2()` can produce more accurate results for base 2,
|
/// details; `log2()` can produce more accurate results for base 2,
|
||||||
/// and `log10()` can produce more accurate results for base 10.
|
/// and `log10()` can produce more accurate results for base 10.
|
||||||
pub fn log(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn log(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let nums = args.get_number_array()?;
|
let nums = args.get_number_array()?;
|
||||||
if nums.len() > 2 {
|
if nums.len() > 2 {
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
@ -299,7 +299,7 @@ fn inner_log(num: f64, base: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the base 2 logarithm of the number.
|
/// Computes the base 2 logarithm of the number.
|
||||||
pub fn log2(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn log2(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_log2(num)?;
|
let result = inner_log2(num)?;
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ fn inner_log2(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the base 10 logarithm of the number.
|
/// Computes the base 10 logarithm of the number.
|
||||||
pub fn log10(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn log10(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_log10(num)?;
|
let result = inner_log10(num)?;
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ fn inner_log10(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the natural logarithm of the number.
|
/// Computes the natural logarithm of the number.
|
||||||
pub fn ln(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn ln(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let num = args.get_number()?;
|
let num = args.get_number()?;
|
||||||
let result = inner_ln(num)?;
|
let result = inner_ln(num)?;
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ fn inner_ln(num: f64) -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value of Euler’s number `e`.
|
/// Return the value of Euler’s number `e`.
|
||||||
pub fn e(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn e(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let result = inner_e()?;
|
let result = inner_e()?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
@ -362,7 +362,7 @@ fn inner_e() -> Result<f64, KclError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
|
/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
|
||||||
pub fn tau(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn tau(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let result = inner_tau()?;
|
let result = inner_tau()?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
|
@ -10,6 +10,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
|
use kittycad::types::OkWebSocketResponseData;
|
||||||
use parse_display::{Display, FromStr};
|
use parse_display::{Display, FromStr};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -21,7 +22,7 @@ use crate::{
|
|||||||
executor::{ExtrudeGroup, MemoryItem, Metadata, SketchGroup, SourceRange},
|
executor::{ExtrudeGroup, MemoryItem, Metadata, SketchGroup, SourceRange},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type StdFn = fn(&mut Args) -> Result<MemoryItem, KclError>;
|
pub type StdFn = fn(Args) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<MemoryItem, KclError>>>>;
|
||||||
pub type FnMap = HashMap<String, StdFn>;
|
pub type FnMap = HashMap<String, StdFn>;
|
||||||
|
|
||||||
pub struct StdLib {
|
pub struct StdLib {
|
||||||
@ -102,15 +103,15 @@ impl Default for StdLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Args<'a> {
|
pub struct Args {
|
||||||
pub args: Vec<MemoryItem>,
|
pub args: Vec<MemoryItem>,
|
||||||
pub source_range: SourceRange,
|
pub source_range: SourceRange,
|
||||||
engine: &'a mut EngineConnection,
|
engine: EngineConnection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Args<'a> {
|
impl Args {
|
||||||
pub fn new(args: Vec<MemoryItem>, source_range: SourceRange, engine: &'a mut EngineConnection) -> Self {
|
pub fn new(args: Vec<MemoryItem>, source_range: SourceRange, engine: EngineConnection) -> Self {
|
||||||
Self {
|
Self {
|
||||||
args,
|
args,
|
||||||
source_range,
|
source_range,
|
||||||
@ -118,8 +119,12 @@ impl<'a> Args<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_modeling_cmd(&mut self, id: uuid::Uuid, cmd: kittycad::types::ModelingCmd) -> Result<(), KclError> {
|
pub async fn send_modeling_cmd(
|
||||||
self.engine.send_modeling_cmd(id, self.source_range, cmd)
|
&self,
|
||||||
|
id: uuid::Uuid,
|
||||||
|
cmd: kittycad::types::ModelingCmd,
|
||||||
|
) -> Result<OkWebSocketResponseData, KclError> {
|
||||||
|
self.engine.send_modeling_cmd(id, self.source_range, cmd).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_user_val_from_json(&self, j: serde_json::Value) -> Result<MemoryItem, KclError> {
|
fn make_user_val_from_json(&self, j: serde_json::Value) -> Result<MemoryItem, KclError> {
|
||||||
@ -443,7 +448,7 @@ impl<'a> Args<'a> {
|
|||||||
|
|
||||||
/// Render a model.
|
/// Render a model.
|
||||||
// This never actually gets called so this is fine.
|
// This never actually gets called so this is fine.
|
||||||
pub fn show(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn show<'a>(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let sketch_group = args.get_sketch_group()?;
|
let sketch_group = args.get_sketch_group()?;
|
||||||
inner_show(sketch_group);
|
inner_show(sketch_group);
|
||||||
|
|
||||||
@ -457,7 +462,7 @@ pub fn show(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
fn inner_show(_sketch: Box<SketchGroup>) {}
|
fn inner_show(_sketch: Box<SketchGroup>) {}
|
||||||
|
|
||||||
/// Returns the length of the given leg.
|
/// Returns the length of the given leg.
|
||||||
pub fn leg_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn leg_length(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
||||||
let result = inner_leg_length(hypotenuse, leg);
|
let result = inner_leg_length(hypotenuse, leg);
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
@ -472,7 +477,7 @@ fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the angle of the given leg for x.
|
/// Returns the angle of the given leg for x.
|
||||||
pub fn leg_angle_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn leg_angle_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
||||||
let result = inner_leg_angle_x(hypotenuse, leg);
|
let result = inner_leg_angle_x(hypotenuse, leg);
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
@ -487,7 +492,7 @@ fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the angle of the given leg for y.
|
/// Returns the angle of the given leg for y.
|
||||||
pub fn leg_angle_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn leg_angle_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
let (hypotenuse, leg) = args.get_hypotenuse_leg()?;
|
||||||
let result = inner_leg_angle_y(hypotenuse, leg);
|
let result = inner_leg_angle_y(hypotenuse, leg);
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
|
@ -11,9 +11,9 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the segment end of x.
|
/// Returns the segment end of x.
|
||||||
pub fn segment_end_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn segment_end_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
||||||
let result = inner_segment_end_x(&segment_name, sketch_group, args)?;
|
let result = inner_segment_end_x(&segment_name, sketch_group, args.clone())?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ pub fn segment_end_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "segEndX",
|
name = "segEndX",
|
||||||
}]
|
}]
|
||||||
fn inner_segment_end_x(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_segment_end_x(segment_name: &str, sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
|
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
message: format!(
|
message: format!(
|
||||||
@ -37,9 +37,9 @@ fn inner_segment_end_x(segment_name: &str, sketch_group: Box<SketchGroup>, args:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the segment end of y.
|
/// Returns the segment end of y.
|
||||||
pub fn segment_end_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn segment_end_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
||||||
let result = inner_segment_end_y(&segment_name, sketch_group, args)?;
|
let result = inner_segment_end_y(&segment_name, sketch_group, args.clone())?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ pub fn segment_end_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "segEndY",
|
name = "segEndY",
|
||||||
}]
|
}]
|
||||||
fn inner_segment_end_y(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_segment_end_y(segment_name: &str, sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
|
let line = sketch_group.get_base_by_name_or_start(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
message: format!(
|
message: format!(
|
||||||
@ -63,9 +63,9 @@ fn inner_segment_end_y(segment_name: &str, sketch_group: Box<SketchGroup>, args:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the last segment of x.
|
/// Returns the last segment of x.
|
||||||
pub fn last_segment_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn last_segment_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let sketch_group = args.get_sketch_group()?;
|
let sketch_group = args.get_sketch_group()?;
|
||||||
let result = inner_last_segment_x(sketch_group, args)?;
|
let result = inner_last_segment_x(sketch_group, args.clone())?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ pub fn last_segment_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "lastSegX",
|
name = "lastSegX",
|
||||||
}]
|
}]
|
||||||
fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let last_line = sketch_group
|
let last_line = sketch_group
|
||||||
.value
|
.value
|
||||||
.last()
|
.last()
|
||||||
@ -93,9 +93,9 @@ fn inner_last_segment_x(sketch_group: Box<SketchGroup>, args: &mut Args) -> Resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the last segment of y.
|
/// Returns the last segment of y.
|
||||||
pub fn last_segment_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn last_segment_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let sketch_group = args.get_sketch_group()?;
|
let sketch_group = args.get_sketch_group()?;
|
||||||
let result = inner_last_segment_y(sketch_group, args)?;
|
let result = inner_last_segment_y(sketch_group, args.clone())?;
|
||||||
|
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ pub fn last_segment_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "lastSegY",
|
name = "lastSegY",
|
||||||
}]
|
}]
|
||||||
fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let last_line = sketch_group
|
let last_line = sketch_group
|
||||||
.value
|
.value
|
||||||
.last()
|
.last()
|
||||||
@ -123,9 +123,9 @@ fn inner_last_segment_y(sketch_group: Box<SketchGroup>, args: &mut Args) -> Resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the length of the segment.
|
/// Returns the length of the segment.
|
||||||
pub fn segment_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn segment_length(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
||||||
let result = inner_segment_length(&segment_name, sketch_group, args)?;
|
let result = inner_segment_length(&segment_name, sketch_group, args.clone())?;
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ pub fn segment_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "segLen",
|
name = "segLen",
|
||||||
}]
|
}]
|
||||||
fn inner_segment_length(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_segment_length(segment_name: &str, sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
message: format!(
|
message: format!(
|
||||||
@ -151,10 +151,10 @@ fn inner_segment_length(segment_name: &str, sketch_group: Box<SketchGroup>, args
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the angle of the segment.
|
/// Returns the angle of the segment.
|
||||||
pub fn segment_angle(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn segment_angle(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
let (segment_name, sketch_group) = args.get_segment_name_sketch_group()?;
|
||||||
|
|
||||||
let result = inner_segment_angle(&segment_name, sketch_group, args)?;
|
let result = inner_segment_angle(&segment_name, sketch_group, args.clone())?;
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ pub fn segment_angle(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "segAng",
|
name = "segAng",
|
||||||
}]
|
}]
|
||||||
fn inner_segment_angle(segment_name: &str, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<f64, KclError> {
|
fn inner_segment_angle(segment_name: &str, sketch_group: Box<SketchGroup>, args: Args) -> Result<f64, KclError> {
|
||||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
message: format!(
|
message: format!(
|
||||||
@ -180,9 +180,9 @@ fn inner_segment_angle(segment_name: &str, sketch_group: Box<SketchGroup>, args:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the angle to match the given length for x.
|
/// Returns the angle to match the given length for x.
|
||||||
pub fn angle_to_match_length_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angle_to_match_length_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
|
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
|
||||||
let result = inner_angle_to_match_length_x(&segment_name, to, sketch_group, args)?;
|
let result = inner_angle_to_match_length_x(&segment_name, to, sketch_group, args.clone())?;
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ fn inner_angle_to_match_length_x(
|
|||||||
segment_name: &str,
|
segment_name: &str,
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<f64, KclError> {
|
) -> Result<f64, KclError> {
|
||||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
@ -235,9 +235,9 @@ fn inner_angle_to_match_length_x(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the angle to match the given length for y.
|
/// Returns the angle to match the given length for y.
|
||||||
pub fn angle_to_match_length_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angle_to_match_length_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
|
let (segment_name, to, sketch_group) = args.get_segment_name_to_number_sketch_group()?;
|
||||||
let result = inner_angle_to_match_length_y(&segment_name, to, sketch_group, args)?;
|
let result = inner_angle_to_match_length_y(&segment_name, to, sketch_group, args.clone())?;
|
||||||
args.make_user_val_from_f64(result)
|
args.make_user_val_from_f64(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ fn inner_angle_to_match_length_y(
|
|||||||
segment_name: &str,
|
segment_name: &str,
|
||||||
to: f64,
|
to: f64,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<f64, KclError> {
|
) -> Result<f64, KclError> {
|
||||||
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
let path = sketch_group.get_path_by_name(segment_name).ok_or_else(|| {
|
||||||
KclError::Type(KclErrorDetails {
|
KclError::Type(KclErrorDetails {
|
||||||
|
@ -33,10 +33,10 @@ pub enum LineToData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line to a point.
|
/// Draw a line to a point.
|
||||||
pub fn line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn line_to(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (LineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (LineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to(data, sketch_group, args)?;
|
let new_sketch_group = inner_line_to(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,10 +44,10 @@ pub fn line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "lineTo",
|
name = "lineTo",
|
||||||
}]
|
}]
|
||||||
fn inner_line_to(
|
async fn inner_line_to(
|
||||||
data: LineToData,
|
data: LineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let to = match data {
|
let to = match data {
|
||||||
@ -70,7 +70,8 @@ fn inner_line_to(
|
|||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
@ -111,10 +112,10 @@ pub enum AxisLineToData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line to a point on the x-axis.
|
/// Draw a line to a point on the x-axis.
|
||||||
pub fn x_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn x_line_to(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_x_line_to(data, sketch_group, args)?;
|
let new_sketch_group = inner_x_line_to(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,10 +123,10 @@ pub fn x_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "xLineTo",
|
name = "xLineTo",
|
||||||
}]
|
}]
|
||||||
fn inner_x_line_to(
|
async fn inner_x_line_to(
|
||||||
data: AxisLineToData,
|
data: AxisLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
|
|
||||||
@ -134,16 +135,16 @@ fn inner_x_line_to(
|
|||||||
AxisLineToData::Point(data) => LineToData::Point([data, from.y]),
|
AxisLineToData::Point(data) => LineToData::Point([data, from.y]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args)?;
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line to a point on the y-axis.
|
/// Draw a line to a point on the y-axis.
|
||||||
pub fn y_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn y_line_to(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AxisLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_y_line_to(data, sketch_group, args)?;
|
let new_sketch_group = inner_y_line_to(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,10 +152,10 @@ pub fn y_line_to(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "yLineTo",
|
name = "yLineTo",
|
||||||
}]
|
}]
|
||||||
fn inner_y_line_to(
|
async fn inner_y_line_to(
|
||||||
data: AxisLineToData,
|
data: AxisLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ fn inner_y_line_to(
|
|||||||
AxisLineToData::Point(data) => LineToData::Point([from.x, data]),
|
AxisLineToData::Point(data) => LineToData::Point([from.x, data]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args)?;
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +185,10 @@ pub enum LineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line.
|
/// Draw a line.
|
||||||
pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn line(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (LineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (LineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_line(data, sketch_group, args)?;
|
let new_sketch_group = inner_line(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ pub fn line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "line",
|
name = "line",
|
||||||
}]
|
}]
|
||||||
fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
async fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let inner_args = match &data {
|
let inner_args = match &data {
|
||||||
LineData::PointWithTag { to, .. } => *to,
|
LineData::PointWithTag { to, .. } => *to,
|
||||||
@ -220,7 +221,8 @@ fn inner_line(data: LineData, sketch_group: Box<SketchGroup>, args: &mut Args) -
|
|||||||
relative: true,
|
relative: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
@ -261,10 +263,10 @@ pub enum AxisLineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line on the x-axis.
|
/// Draw a line on the x-axis.
|
||||||
pub fn x_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn x_line(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_x_line(data, sketch_group, args)?;
|
let new_sketch_group = inner_x_line(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,25 +274,25 @@ pub fn x_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "xLine",
|
name = "xLine",
|
||||||
}]
|
}]
|
||||||
fn inner_x_line(
|
async fn inner_x_line(
|
||||||
data: AxisLineData,
|
data: AxisLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let line_data = match data {
|
let line_data = match data {
|
||||||
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [length, 0.0], tag },
|
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [length, 0.0], tag },
|
||||||
AxisLineData::Length(length) => LineData::Point([length, 0.0]),
|
AxisLineData::Length(length) => LineData::Point([length, 0.0]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_line(line_data, sketch_group, args)?;
|
let new_sketch_group = inner_line(line_data, sketch_group, args).await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a line on the y-axis.
|
/// Draw a line on the y-axis.
|
||||||
pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn y_line(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AxisLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_y_line(data, sketch_group, args)?;
|
let new_sketch_group = inner_y_line(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,17 +300,17 @@ pub fn y_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "yLine",
|
name = "yLine",
|
||||||
}]
|
}]
|
||||||
fn inner_y_line(
|
async fn inner_y_line(
|
||||||
data: AxisLineData,
|
data: AxisLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let line_data = match data {
|
let line_data = match data {
|
||||||
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [0.0, length], tag },
|
AxisLineData::LengthWithTag { length, tag } => LineData::PointWithTag { to: [0.0, length], tag },
|
||||||
AxisLineData::Length(length) => LineData::Point([0.0, length]),
|
AxisLineData::Length(length) => LineData::Point([0.0, length]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_line(line_data, sketch_group, args)?;
|
let new_sketch_group = inner_line(line_data, sketch_group, args).await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,10 +333,10 @@ pub enum AngledLineData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line.
|
/// Draw an angled line.
|
||||||
pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,10 +344,10 @@ pub fn angled_line(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLine",
|
name = "angledLine",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line(
|
async fn inner_angled_line(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let (angle, length) = match &data {
|
let (angle, length) = match &data {
|
||||||
@ -393,7 +395,8 @@ fn inner_angled_line(
|
|||||||
relative,
|
relative,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut new_sketch_group = sketch_group.clone();
|
let mut new_sketch_group = sketch_group.clone();
|
||||||
new_sketch_group.value.push(current_path);
|
new_sketch_group.value.push(current_path);
|
||||||
@ -401,10 +404,10 @@ fn inner_angled_line(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line of a given x length.
|
/// Draw an angled line of a given x length.
|
||||||
pub fn angled_line_of_x_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line_of_x_length(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_of_x_length(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line_of_x_length(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,10 +415,10 @@ pub fn angled_line_of_x_length(args: &mut Args) -> Result<MemoryItem, KclError>
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLineOfXLength",
|
name = "angledLineOfXLength",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line_of_x_length(
|
async fn inner_angled_line_of_x_length(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let (angle, length) = match &data {
|
let (angle, length) = match &data {
|
||||||
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
|
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
|
||||||
@ -432,7 +435,8 @@ fn inner_angled_line_of_x_length(
|
|||||||
},
|
},
|
||||||
sketch_group,
|
sketch_group,
|
||||||
args,
|
args,
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
@ -456,10 +460,10 @@ pub enum AngledLineToData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line to a given x coordinate.
|
/// Draw an angled line to a given x coordinate.
|
||||||
pub fn angled_line_to_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line_to_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_to_x(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line_to_x(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,10 +471,10 @@ pub fn angled_line_to_x(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLineToX",
|
name = "angledLineToX",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line_to_x(
|
async fn inner_angled_line_to_x(
|
||||||
data: AngledLineToData,
|
data: AngledLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let (angle, x_to) = match &data {
|
let (angle, x_to) = match &data {
|
||||||
@ -490,15 +494,16 @@ fn inner_angled_line_to_x(
|
|||||||
},
|
},
|
||||||
sketch_group,
|
sketch_group,
|
||||||
args,
|
args,
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line of a given y length.
|
/// Draw an angled line of a given y length.
|
||||||
pub fn angled_line_of_y_length(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line_of_y_length(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngledLineData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line_of_y_length(data, sketch_group, args).await?;
|
||||||
|
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
@ -507,10 +512,10 @@ pub fn angled_line_of_y_length(args: &mut Args) -> Result<MemoryItem, KclError>
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLineOfYLength",
|
name = "angledLineOfYLength",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line_of_y_length(
|
async fn inner_angled_line_of_y_length(
|
||||||
data: AngledLineData,
|
data: AngledLineData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let (angle, length) = match &data {
|
let (angle, length) = match &data {
|
||||||
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
|
AngledLineData::AngleWithTag { angle, length, .. } => (*angle, *length),
|
||||||
@ -527,16 +532,17 @@ fn inner_angled_line_of_y_length(
|
|||||||
},
|
},
|
||||||
sketch_group,
|
sketch_group,
|
||||||
args,
|
args,
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line to a given y coordinate.
|
/// Draw an angled line to a given y coordinate.
|
||||||
pub fn angled_line_to_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line_to_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngledLineToData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_angled_line_to_y(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line_to_y(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,10 +550,10 @@ pub fn angled_line_to_y(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLineToY",
|
name = "angledLineToY",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line_to_y(
|
async fn inner_angled_line_to_y(
|
||||||
data: AngledLineToData,
|
data: AngledLineToData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let (angle, y_to) = match &data {
|
let (angle, y_to) = match &data {
|
||||||
@ -567,7 +573,8 @@ fn inner_angled_line_to_y(
|
|||||||
},
|
},
|
||||||
sketch_group,
|
sketch_group,
|
||||||
args,
|
args,
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,9 +595,9 @@ pub struct AngeledLineThatIntersectsData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an angled line that intersects with a given line.
|
/// Draw an angled line that intersects with a given line.
|
||||||
pub fn angled_line_that_intersects(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn angled_line_that_intersects(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (AngeledLineThatIntersectsData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (AngeledLineThatIntersectsData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
let new_sketch_group = inner_angled_line_that_intersects(data, sketch_group, args)?;
|
let new_sketch_group = inner_angled_line_that_intersects(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,10 +605,10 @@ pub fn angled_line_that_intersects(args: &mut Args) -> Result<MemoryItem, KclErr
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "angledLineThatIntersects",
|
name = "angledLineThatIntersects",
|
||||||
}]
|
}]
|
||||||
fn inner_angled_line_that_intersects(
|
async fn inner_angled_line_that_intersects(
|
||||||
data: AngeledLineThatIntersectsData,
|
data: AngeledLineThatIntersectsData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let intersect_path = sketch_group
|
let intersect_path = sketch_group
|
||||||
.get_path_by_name(&data.intersect_tag)
|
.get_path_by_name(&data.intersect_tag)
|
||||||
@ -630,15 +637,15 @@ fn inner_angled_line_that_intersects(
|
|||||||
LineToData::Point(to.into())
|
LineToData::Point(to.into())
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args)?;
|
let new_sketch_group = inner_line_to(line_to_data, sketch_group, args).await?;
|
||||||
Ok(new_sketch_group)
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a sketch at a given point.
|
/// Start a sketch at a given point.
|
||||||
pub fn start_sketch_at(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn start_sketch_at(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let data: LineData = args.get_data()?;
|
let data: LineData = args.get_data()?;
|
||||||
|
|
||||||
let sketch_group = inner_start_sketch_at(data, args)?;
|
let sketch_group = inner_start_sketch_at(data, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(sketch_group))
|
Ok(MemoryItem::SketchGroup(sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +653,7 @@ pub fn start_sketch_at(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "startSketchAt",
|
name = "startSketchAt",
|
||||||
}]
|
}]
|
||||||
fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
async fn inner_start_sketch_at(data: LineData, args: Args) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let to = match &data {
|
let to = match &data {
|
||||||
LineData::PointWithTag { to, .. } => *to,
|
LineData::PointWithTag { to, .. } => *to,
|
||||||
LineData::Point(to) => *to,
|
LineData::Point(to) => *to,
|
||||||
@ -655,7 +662,7 @@ fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGr
|
|||||||
let id = uuid::Uuid::new_v4();
|
let id = uuid::Uuid::new_v4();
|
||||||
let path_id = uuid::Uuid::new_v4();
|
let path_id = uuid::Uuid::new_v4();
|
||||||
|
|
||||||
args.send_modeling_cmd(path_id, ModelingCmd::StartPath {})?;
|
args.send_modeling_cmd(path_id, ModelingCmd::StartPath {}).await?;
|
||||||
args.send_modeling_cmd(
|
args.send_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::MovePathPen {
|
ModelingCmd::MovePathPen {
|
||||||
@ -666,7 +673,8 @@ fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGr
|
|||||||
z: 0.0,
|
z: 0.0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let current_path = BasePath {
|
let current_path = BasePath {
|
||||||
from: to,
|
from: to,
|
||||||
@ -694,10 +702,10 @@ fn inner_start_sketch_at(data: LineData, args: &mut Args) -> Result<Box<SketchGr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Close the current sketch.
|
/// Close the current sketch.
|
||||||
pub fn close(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn close(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let sketch_group = args.get_sketch_group()?;
|
let sketch_group = args.get_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_close(sketch_group, args)?;
|
let new_sketch_group = inner_close(sketch_group, args).await?;
|
||||||
|
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
@ -706,7 +714,7 @@ pub fn close(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "close",
|
name = "close",
|
||||||
}]
|
}]
|
||||||
fn inner_close(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
async fn inner_close(sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
let to: Point2d = sketch_group.start.from.into();
|
let to: Point2d = sketch_group.start.from.into();
|
||||||
|
|
||||||
@ -717,7 +725,8 @@ fn inner_close(sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<Sk
|
|||||||
ModelingCmd::ClosePath {
|
ModelingCmd::ClosePath {
|
||||||
path_id: sketch_group.id,
|
path_id: sketch_group.id,
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut new_sketch_group = sketch_group.clone();
|
let mut new_sketch_group = sketch_group.clone();
|
||||||
new_sketch_group.value.push(Path::ToPoint {
|
new_sketch_group.value.push(Path::ToPoint {
|
||||||
@ -784,10 +793,10 @@ pub enum ArcData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an arc.
|
/// Draw an arc.
|
||||||
pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn arc(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (ArcData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (ArcData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_arc(data, sketch_group, args)?;
|
let new_sketch_group = inner_arc(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,7 +804,7 @@ pub fn arc(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "arc",
|
name = "arc",
|
||||||
}]
|
}]
|
||||||
fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) -> Result<Box<SketchGroup>, KclError> {
|
async fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: Args) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
let from: Point2d = sketch_group.get_coords_from_paths()?;
|
||||||
|
|
||||||
let (center, angle_start, angle_end, radius, end) = match &data {
|
let (center, angle_start, angle_end, radius, end) = match &data {
|
||||||
@ -844,7 +853,8 @@ fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) ->
|
|||||||
relative: false,
|
relative: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// TODO: Dont do this (move path pen) - mike
|
// TODO: Dont do this (move path pen) - mike
|
||||||
// lets review what the needs are here and see if any existing arc endpoints can accomplish this
|
// lets review what the needs are here and see if any existing arc endpoints can accomplish this
|
||||||
@ -863,7 +873,8 @@ fn inner_arc(data: ArcData, sketch_group: Box<SketchGroup>, args: &mut Args) ->
|
|||||||
z: 0.0,
|
z: 0.0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
@ -916,10 +927,10 @@ pub enum BezierData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a bezier curve.
|
/// Draw a bezier curve.
|
||||||
pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
|
pub async fn bezier_curve(args: Args) -> Result<MemoryItem, KclError> {
|
||||||
let (data, sketch_group): (BezierData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
let (data, sketch_group): (BezierData, Box<SketchGroup>) = args.get_data_and_sketch_group()?;
|
||||||
|
|
||||||
let new_sketch_group = inner_bezier_curve(data, sketch_group, args)?;
|
let new_sketch_group = inner_bezier_curve(data, sketch_group, args).await?;
|
||||||
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
Ok(MemoryItem::SketchGroup(new_sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,10 +938,10 @@ pub fn bezier_curve(args: &mut Args) -> Result<MemoryItem, KclError> {
|
|||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "bezierCurve",
|
name = "bezierCurve",
|
||||||
}]
|
}]
|
||||||
fn inner_bezier_curve(
|
async fn inner_bezier_curve(
|
||||||
data: BezierData,
|
data: BezierData,
|
||||||
sketch_group: Box<SketchGroup>,
|
sketch_group: Box<SketchGroup>,
|
||||||
args: &mut Args,
|
args: Args,
|
||||||
) -> Result<Box<SketchGroup>, KclError> {
|
) -> Result<Box<SketchGroup>, KclError> {
|
||||||
let from = sketch_group.get_coords_from_paths()?;
|
let from = sketch_group.get_coords_from_paths()?;
|
||||||
|
|
||||||
@ -970,7 +981,8 @@ fn inner_bezier_curve(
|
|||||||
relative,
|
relative,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let current_path = Path::ToPoint {
|
let current_path = Path::ToPoint {
|
||||||
base: BasePath {
|
base: BasePath {
|
||||||
|
@ -21,11 +21,12 @@ pub async fn execute_wasm(
|
|||||||
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
|
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
|
||||||
let mut mem: kcl_lib::executor::ProgramMemory = serde_json::from_str(memory_str).map_err(|e| e.to_string())?;
|
let mut mem: kcl_lib::executor::ProgramMemory = serde_json::from_str(memory_str).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let mut engine = kcl_lib::engine::EngineConnection::new(manager)
|
let engine = kcl_lib::engine::EngineConnection::new(manager)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{:?}", e))?;
|
||||||
|
|
||||||
let memory = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &mut engine)
|
let memory = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &engine)
|
||||||
|
.await
|
||||||
.map_err(String::from)?;
|
.map_err(String::from)?;
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
||||||
// gloo-serialize crate instead.
|
// gloo-serialize crate instead.
|
||||||
|
@ -35,12 +35,12 @@ async fn execute_and_snapshot(code: &str) -> Result<image::DynamicImage> {
|
|||||||
let parser = kcl_lib::parser::Parser::new(tokens);
|
let parser = kcl_lib::parser::Parser::new(tokens);
|
||||||
let program = parser.ast()?;
|
let program = parser.ast()?;
|
||||||
let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
|
let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
|
||||||
let mut engine = kcl_lib::engine::EngineConnection::new(ws).await?;
|
let engine = kcl_lib::engine::EngineConnection::new(ws).await?;
|
||||||
let _ = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &mut engine)?;
|
let _ = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &engine).await?;
|
||||||
|
|
||||||
// Send a snapshot request to the engine.
|
// Send a snapshot request to the engine.
|
||||||
let resp = engine
|
let resp = engine
|
||||||
.send_modeling_cmd_get_response(
|
.send_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
kcl_lib::executor::SourceRange::default(),
|
kcl_lib::executor::SourceRange::default(),
|
||||||
kittycad::types::ModelingCmd::TakeSnapshot {
|
kittycad::types::ModelingCmd::TakeSnapshot {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 69 KiB |
@ -37,13 +37,9 @@ async fn setup(code: &str, name: &str) -> Result<(EngineConnection, Program, uui
|
|||||||
let parser = kcl_lib::parser::Parser::new(tokens);
|
let parser = kcl_lib::parser::Parser::new(tokens);
|
||||||
let program = parser.ast()?;
|
let program = parser.ast()?;
|
||||||
let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
|
let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
|
||||||
let mut engine = kcl_lib::engine::EngineConnection::new(ws).await?;
|
let engine = kcl_lib::engine::EngineConnection::new(ws).await?;
|
||||||
let memory = kcl_lib::executor::execute(
|
let memory =
|
||||||
program.clone(),
|
kcl_lib::executor::execute(program.clone(), &mut mem, kcl_lib::executor::BodyType::Root, &engine).await?;
|
||||||
&mut mem,
|
|
||||||
kcl_lib::executor::BodyType::Root,
|
|
||||||
&mut engine,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// We need to get the sketch ID.
|
// We need to get the sketch ID.
|
||||||
// Get the sketch group ID from memory.
|
// Get the sketch group ID from memory.
|
||||||
@ -53,7 +49,8 @@ async fn setup(code: &str, name: &str) -> Result<(EngineConnection, Program, uui
|
|||||||
let sketch_id = sketch_group.id;
|
let sketch_id = sketch_group.id;
|
||||||
|
|
||||||
let plane_id = uuid::Uuid::new_v4();
|
let plane_id = uuid::Uuid::new_v4();
|
||||||
engine.send_modeling_cmd(
|
engine
|
||||||
|
.send_modeling_cmd(
|
||||||
plane_id,
|
plane_id,
|
||||||
SourceRange::default(),
|
SourceRange::default(),
|
||||||
ModelingCmd::MakePlane {
|
ModelingCmd::MakePlane {
|
||||||
@ -63,12 +60,14 @@ async fn setup(code: &str, name: &str) -> Result<(EngineConnection, Program, uui
|
|||||||
x_axis: Point3D { x: 1.0, y: 0.0, z: 0.0 },
|
x_axis: Point3D { x: 1.0, y: 0.0, z: 0.0 },
|
||||||
y_axis: Point3D { x: 0.0, y: 1.0, z: 0.0 },
|
y_axis: Point3D { x: 0.0, y: 1.0, z: 0.0 },
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Enter sketch mode.
|
// Enter sketch mode.
|
||||||
// We can't get control points without being in sketch mode.
|
// We can't get control points without being in sketch mode.
|
||||||
// You can however get path info without sketch mode.
|
// You can however get path info without sketch mode.
|
||||||
engine.send_modeling_cmd(
|
engine
|
||||||
|
.send_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
SourceRange::default(),
|
SourceRange::default(),
|
||||||
ModelingCmd::SketchModeEnable {
|
ModelingCmd::SketchModeEnable {
|
||||||
@ -76,15 +75,18 @@ async fn setup(code: &str, name: &str) -> Result<(EngineConnection, Program, uui
|
|||||||
ortho: true,
|
ortho: true,
|
||||||
plane_id,
|
plane_id,
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
// We can't get control points of an existing sketch without being in edit mode.
|
// We can't get control points of an existing sketch without being in edit mode.
|
||||||
engine.send_modeling_cmd(
|
engine
|
||||||
|
.send_modeling_cmd(
|
||||||
uuid::Uuid::new_v4(),
|
uuid::Uuid::new_v4(),
|
||||||
SourceRange::default(),
|
SourceRange::default(),
|
||||||
ModelingCmd::EditModeEnter { target: sketch_id },
|
ModelingCmd::EditModeEnter { target: sketch_id },
|
||||||
)?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok((engine, program, sketch_id))
|
Ok((engine, program, sketch_id))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user