Compare commits
2 Commits
batch-take
...
kcl_prelud
Author | SHA1 | Date | |
---|---|---|---|
ddce447c0b | |||
e8769eb543 |
1160
src/wasm-lib/Cargo.lock
generated
1160
src/wasm-lib/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -59,7 +59,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
kittycad = { path = "../../../kittycad.rs/kittycad", default-features = false, features = ["js", "requests"] }
|
||||
kittycad = { version = "0.2.60", default-features = false, features = ["js", "requests"] }
|
||||
kittycad-execution-plan = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
|
||||
kittycad-execution-plan-macros = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
|
||||
kittycad-execution-plan-traits = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
|
||||
|
@ -8,6 +8,7 @@ description = "A new executor for KCL which compiles to Execution Plans"
|
||||
[dependencies]
|
||||
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
||||
kcl-lib = { path = "../kcl" }
|
||||
kcl-macros = { path = "../kcl-macros/" }
|
||||
kittycad = { workspace = true }
|
||||
kittycad-execution-plan = { workspace = true }
|
||||
kittycad-execution-plan-traits = { workspace = true }
|
||||
|
@ -11,6 +11,8 @@ use kcl_lib::{
|
||||
ast,
|
||||
ast::types::{BodyItem, FunctionExpressionParts, KclNone, LiteralValue, Program},
|
||||
};
|
||||
extern crate alloc;
|
||||
use kcl_macros::parse_file;
|
||||
use kcl_value_group::into_single_value;
|
||||
use kittycad_execution_plan::{self as ep, Destination, Instruction};
|
||||
use kittycad_execution_plan_traits as ept;
|
||||
@ -24,9 +26,11 @@ use self::{
|
||||
};
|
||||
|
||||
/// Execute a KCL program by compiling into an execution plan, then running that.
|
||||
pub async fn execute(ast: Program, session: &mut Option<Session>) -> Result<ep::Memory, Error> {
|
||||
/// Include a `prelude.kcl` inlined as a `Program` struct thanks to a proc_macro `parse!`.
|
||||
/// This makes additional functions available to the user.
|
||||
pub async fn execute(ast_user: Program, session: &mut Option<Session>) -> Result<ep::Memory, Error> {
|
||||
let mut planner = Planner::new();
|
||||
let (plan, _retval) = planner.build_plan(ast)?;
|
||||
let (plan, _retval) = planner.build_plan(ast_user)?;
|
||||
let mut mem = ep::Memory::default();
|
||||
ep::execute(&mut mem, plan, session).await?;
|
||||
Ok(mem)
|
||||
@ -54,7 +58,9 @@ impl Planner {
|
||||
|
||||
/// If successful, return the KCEP instructions for executing the given program.
|
||||
/// If the program is a function with a return, then it also returns the KCL function's return value.
|
||||
fn build_plan(&mut self, program: Program) -> Result<(Vec<Instruction>, Option<EpBinding>), CompileError> {
|
||||
fn build_plan(&mut self, ast_user: Program) -> Result<(Vec<Instruction>, Option<EpBinding>), CompileError> {
|
||||
let ast_prelude = parse_file!("./prelude.kcl");
|
||||
let program = ast_prelude.merge(ast_user);
|
||||
program
|
||||
.body
|
||||
.into_iter()
|
||||
|
@ -32,23 +32,23 @@ impl<'a> Context<'a> {
|
||||
/// Unary operator macro to quickly create new bindings.
|
||||
macro_rules! define_unary {
|
||||
() => {};
|
||||
($h:ident$( $r:ident)*) => {
|
||||
($fn_name:ident$( $rest:ident)*) => {
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(test, derive(Eq, PartialEq))]
|
||||
pub struct $h;
|
||||
pub struct $fn_name;
|
||||
|
||||
impl Callable for $h {
|
||||
impl Callable for $fn_name {
|
||||
fn call(&self, ctx: &mut Context<'_>, mut args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
|
||||
if args.len() > 1 {
|
||||
return Err(CompileError::TooManyArgs {
|
||||
fn_name: "$h".into(),
|
||||
fn_name: "$fn_name".into(),
|
||||
maximum: 1,
|
||||
actual: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let not_enough_args = CompileError::NotEnoughArgs {
|
||||
fn_name: "$h".into(),
|
||||
fn_name: "$fn_name".into(),
|
||||
required: 1,
|
||||
actual: args.len(),
|
||||
};
|
||||
@ -61,7 +61,7 @@ macro_rules! define_unary {
|
||||
let instructions = vec![
|
||||
Instruction::UnaryArithmetic {
|
||||
arithmetic: UnaryArithmetic {
|
||||
operation: UnaryOperation::$h,
|
||||
operation: UnaryOperation::$fn_name,
|
||||
operand: Operand::Reference(arg0)
|
||||
},
|
||||
destination: Destination::Address(destination)
|
||||
@ -75,7 +75,7 @@ macro_rules! define_unary {
|
||||
}
|
||||
}
|
||||
|
||||
define_unary!($($r)*);
|
||||
define_unary!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
@ -115,27 +115,27 @@ impl Callable for Id {
|
||||
/// Binary operator macro to quickly create new bindings.
|
||||
macro_rules! define_binary {
|
||||
() => {};
|
||||
($h:ident$( $r:ident)*) => {
|
||||
($fn_name:ident$( $rest:ident)*) => {
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(test, derive(Eq, PartialEq))]
|
||||
pub struct $h;
|
||||
pub struct $fn_name;
|
||||
|
||||
impl Callable for $h {
|
||||
impl Callable for $fn_name {
|
||||
fn call(&self, ctx: &mut Context<'_>, mut args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
|
||||
let len = args.len();
|
||||
if len > 2 {
|
||||
return Err(CompileError::TooManyArgs {
|
||||
fn_name: "$h".into(),
|
||||
fn_name: "$fn_name".into(),
|
||||
maximum: 2,
|
||||
actual: len,
|
||||
});
|
||||
}
|
||||
let not_enough_args = CompileError::NotEnoughArgs {
|
||||
fn_name: "$h".into(),
|
||||
fn_name: "$fn_name".into(),
|
||||
required: 2,
|
||||
actual: len,
|
||||
};
|
||||
const ERR: &str = "cannot use composite values (e.g. array) as arguments to $h";
|
||||
const ERR: &str = "cannot use composite values (e.g. array) as arguments to $fn_name";
|
||||
let EpBinding::Single(arg1) = args.pop().ok_or(not_enough_args.clone())? else {
|
||||
return Err(CompileError::InvalidOperand(ERR));
|
||||
};
|
||||
@ -146,7 +146,7 @@ macro_rules! define_binary {
|
||||
Ok(EvalPlan {
|
||||
instructions: vec![Instruction::BinaryArithmetic {
|
||||
arithmetic: BinaryArithmetic {
|
||||
operation: BinaryOperation::$h,
|
||||
operation: BinaryOperation::$fn_name,
|
||||
operand0: Operand::Reference(arg0),
|
||||
operand1: Operand::Reference(arg1),
|
||||
},
|
||||
@ -157,7 +157,7 @@ macro_rules! define_binary {
|
||||
}
|
||||
}
|
||||
|
||||
define_binary!($($r)*);
|
||||
define_binary!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1442,3 +1442,23 @@ async fn cos_sin_pi() {
|
||||
// Constants don't live in memory.
|
||||
assert_eq!(*z, constants::PI);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn kcl_prelude() {
|
||||
let program = "
|
||||
let the_answer_to_the_universe_is = hey_from_one_of_the_devs_of_the_past_i_wish_you_a_great_day_and_maybe_gave_you_a_little_smile_as_youve_found_this()
|
||||
";
|
||||
let (_plan, scope, _) = must_plan(program);
|
||||
let Some(EpBinding::Single(the_answer_to_the_universe_is)) = scope.get("the_answer_to_the_universe_is") else {
|
||||
panic!(
|
||||
"Unexpected binding for variable 'the_answer_to_the_universe_is': {:?}",
|
||||
scope.get("the_answer_to_the_universe_is")
|
||||
);
|
||||
};
|
||||
let ast = kcl_lib::parser::Parser::new(kcl_lib::token::lexer(program))
|
||||
.ast()
|
||||
.unwrap();
|
||||
let mem = crate::execute(ast, &mut None).await.unwrap();
|
||||
use ept::ReadMemory;
|
||||
assert_eq!(*mem.get(the_answer_to_the_universe_is).unwrap(), Primitive::from(42i64));
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ use syn::{parse_macro_input, LitStr};
|
||||
/// This macro takes exactly one argument: A string literal containing KCL.
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// extern crate alloc;
|
||||
/// use kcl_compile_macro::parse_kcl;
|
||||
/// let ast: kcl_lib::ast::types::Program = parse_kcl!("const y = 4");
|
||||
/// ```
|
||||
@ -21,3 +20,14 @@ pub fn parse(input: TokenStream) -> TokenStream {
|
||||
let ast_struct = ast.bake(&Default::default());
|
||||
quote!(#ast_struct).into()
|
||||
}
|
||||
|
||||
/// Same as `parse!` but read in a file.
|
||||
#[proc_macro]
|
||||
pub fn parse_file(input: TokenStream) -> TokenStream {
|
||||
let file_name = parse_macro_input!(input as LitStr);
|
||||
let kcl_src = std::fs::read_to_string(file_name.value()).unwrap();
|
||||
let tokens = kcl_lib::token::lexer(&kcl_src);
|
||||
let ast = kcl_lib::parser::Parser::new(tokens).ast().unwrap();
|
||||
let ast_struct = ast.bake(&Default::default());
|
||||
quote!(#ast_struct).into()
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ keywords = ["kcl", "KittyCAD", "CAD"]
|
||||
anyhow = { version = "1.0.81", features = ["backtrace"] }
|
||||
async-recursion = "1.0.5"
|
||||
async-trait = "0.1.77"
|
||||
boxcar = "0.2.4"
|
||||
chrono = "0.4.35"
|
||||
clap = { version = "4.5.2", features = ["cargo", "derive", "env", "unicode"], optional = true }
|
||||
dashmap = "5.5.3"
|
||||
|
@ -75,7 +75,6 @@ pub async fn modify_ast_for_sketch(
|
||||
// Let's get the path info.
|
||||
let resp = engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
SourceRange::default(),
|
||||
ModelingCmd::PathGetInfo { path_id: sketch_id },
|
||||
@ -100,7 +99,6 @@ pub async fn modify_ast_for_sketch(
|
||||
for segment in &path_info.segments {
|
||||
if let Some(command_id) = &segment.command_id {
|
||||
let h = engine.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
SourceRange::default(),
|
||||
ModelingCmd::CurveGetControlPoints { curve_id: *command_id },
|
||||
|
@ -351,6 +351,31 @@ impl Program {
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Merge two `Program`s together.
|
||||
pub fn merge(self, ast_other: Program) -> Program {
|
||||
let mut body_new: Vec<BodyItem> = vec![];
|
||||
body_new.extend(self.body);
|
||||
body_new.extend(ast_other.body);
|
||||
|
||||
let mut non_code_nodes_new: HashMap<usize, Vec<NonCodeNode>> = HashMap::new();
|
||||
non_code_nodes_new.extend(self.non_code_meta.non_code_nodes);
|
||||
non_code_nodes_new.extend(ast_other.non_code_meta.non_code_nodes);
|
||||
|
||||
let mut start_new: Vec<NonCodeNode> = vec![];
|
||||
start_new.extend(self.non_code_meta.start);
|
||||
start_new.extend(ast_other.non_code_meta.start);
|
||||
|
||||
Program {
|
||||
start: self.start,
|
||||
end: self.end + (ast_other.end - ast_other.start),
|
||||
body: body_new,
|
||||
non_code_meta: NonCodeMeta {
|
||||
non_code_nodes: non_code_nodes_new,
|
||||
start: start_new,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValueMeta {
|
||||
|
@ -29,7 +29,6 @@ pub struct EngineConnection {
|
||||
responses: Arc<DashMap<uuid::Uuid, WebSocketResponse>>,
|
||||
tcp_read_handle: Arc<TcpReadHandle>,
|
||||
socket_health: Arc<Mutex<SocketHealth>>,
|
||||
batch: Arc<Mutex<Vec<WebSocketRequest>>>,
|
||||
}
|
||||
|
||||
pub struct TcpRead {
|
||||
@ -155,136 +154,27 @@ impl EngineConnection {
|
||||
}),
|
||||
responses,
|
||||
socket_health,
|
||||
batch: Arc::new(Mutex::new(Vec::new())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn is_cmd_with_return_values(cmd: &kittycad::types::ModelingCmd) -> bool {
|
||||
let (kittycad::types::ModelingCmd::Export { .. }
|
||||
| kittycad::types::ModelingCmd::Extrude { .. }
|
||||
| kittycad::types::ModelingCmd::SketchModeDisable { .. }
|
||||
| kittycad::types::ModelingCmd::ObjectBringToFront { .. }
|
||||
| kittycad::types::ModelingCmd::SelectWithPoint { .. }
|
||||
| kittycad::types::ModelingCmd::HighlightSetEntity { .. }
|
||||
| kittycad::types::ModelingCmd::EntityGetChildUuid { .. }
|
||||
| kittycad::types::ModelingCmd::EntityGetNumChildren { .. }
|
||||
| kittycad::types::ModelingCmd::EntityGetParentId { .. }
|
||||
| kittycad::types::ModelingCmd::EntityGetAllChildUuids { .. }
|
||||
| kittycad::types::ModelingCmd::CameraDragMove { .. }
|
||||
| kittycad::types::ModelingCmd::CameraDragEnd { .. }
|
||||
| kittycad::types::ModelingCmd::DefaultCameraGetSettings { .. }
|
||||
| kittycad::types::ModelingCmd::DefaultCameraZoom { .. }
|
||||
| kittycad::types::ModelingCmd::SelectGet { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetAllEdgeFaces { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetAllOppositeEdges { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetOppositeEdge { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetNextAdjacentEdge { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetPrevAdjacentEdge { .. }
|
||||
| kittycad::types::ModelingCmd::GetEntityType { .. }
|
||||
| kittycad::types::ModelingCmd::CurveGetControlPoints { .. }
|
||||
| kittycad::types::ModelingCmd::CurveGetType { .. }
|
||||
| kittycad::types::ModelingCmd::MouseClick { .. }
|
||||
| kittycad::types::ModelingCmd::TakeSnapshot { .. }
|
||||
| kittycad::types::ModelingCmd::PathGetInfo { .. }
|
||||
| kittycad::types::ModelingCmd::PathGetCurveUuidsForVertices { .. }
|
||||
| kittycad::types::ModelingCmd::PathGetVertexUuids { .. }
|
||||
| kittycad::types::ModelingCmd::CurveGetEndPoints { .. }
|
||||
| kittycad::types::ModelingCmd::FaceIsPlanar { .. }
|
||||
| kittycad::types::ModelingCmd::FaceGetPosition { .. }
|
||||
| kittycad::types::ModelingCmd::FaceGetGradient { .. }
|
||||
| kittycad::types::ModelingCmd::PlaneIntersectAndProject { .. }
|
||||
| kittycad::types::ModelingCmd::ImportFiles { .. }
|
||||
| kittycad::types::ModelingCmd::Mass { .. }
|
||||
| kittycad::types::ModelingCmd::Volume { .. }
|
||||
| kittycad::types::ModelingCmd::Density { .. }
|
||||
| kittycad::types::ModelingCmd::SurfaceArea { .. }
|
||||
| kittycad::types::ModelingCmd::CenterOfMass { .. }
|
||||
| kittycad::types::ModelingCmd::GetSketchModePlane { .. }
|
||||
| kittycad::types::ModelingCmd::EntityGetDistance { .. }
|
||||
| kittycad::types::ModelingCmd::EntityLinearPattern { .. }
|
||||
| kittycad::types::ModelingCmd::EntityCircularPattern { .. }
|
||||
| kittycad::types::ModelingCmd::Solid3DGetExtrusionFaceInfo { .. }) = cmd
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl EngineManager for EngineConnection {
|
||||
async fn send_modeling_cmd(
|
||||
&self,
|
||||
flush_batch: bool,
|
||||
id: uuid::Uuid,
|
||||
source_range: crate::executor::SourceRange,
|
||||
cmd: kittycad::types::ModelingCmd,
|
||||
) -> Result<OkWebSocketResponseData, KclError> {
|
||||
let req = WebSocketRequest::ModelingCmdReq {
|
||||
cmd: cmd.clone(),
|
||||
cmd_id: id,
|
||||
};
|
||||
|
||||
println!("req {:?}", req);
|
||||
|
||||
if !flush_batch {
|
||||
self.batch.lock().unwrap().push(req);
|
||||
}
|
||||
|
||||
// If the batch only has this one command that expects a return value,
|
||||
// fire it right away, or if we want to flush batch queue.
|
||||
let is_sending = (is_cmd_with_return_values(&cmd) && self.batch.lock().unwrap().len() == 1)
|
||||
|| flush_batch
|
||||
|| is_cmd_with_return_values(&cmd);
|
||||
|
||||
// Return a fake modeling_request empty response.
|
||||
if !is_sending {
|
||||
println!("fake {:?}", cmd);
|
||||
return Ok(OkWebSocketResponseData::Modeling {
|
||||
modeling_response: kittycad::types::OkModelingCmdResponse::Empty {}
|
||||
});
|
||||
}
|
||||
|
||||
let batched_requests =
|
||||
WebSocketRequest::ModelingCmdBatchReq {
|
||||
requests: self.batch.lock().unwrap().iter().fold(vec![], |mut acc, val| {
|
||||
let WebSocketRequest::ModelingCmdReq { cmd, cmd_id } = val else { return acc; };
|
||||
acc.push(kittycad::types::ModelingCmdReq {
|
||||
cmd: cmd.clone(),
|
||||
cmd_id: *cmd_id,
|
||||
});
|
||||
acc
|
||||
}),
|
||||
batch_id: uuid::Uuid::new_v4()
|
||||
};
|
||||
|
||||
let final_req = if self.batch.lock().unwrap().len() == 1 {
|
||||
self.batch.lock().unwrap().get(0).unwrap().clone()
|
||||
} else {
|
||||
batched_requests
|
||||
};
|
||||
|
||||
// Throw away the old batch queue.
|
||||
self.batch.lock().unwrap().clear();
|
||||
|
||||
println!("final req {:?}", final_req);
|
||||
|
||||
// We pop off the responses to cleanup our mappings.
|
||||
let id_final = match final_req {
|
||||
WebSocketRequest::ModelingCmdBatchReq { requests: _, batch_id } => batch_id,
|
||||
WebSocketRequest::ModelingCmdReq { cmd: _, cmd_id } => cmd_id,
|
||||
_ => panic!("should not be possible"),
|
||||
};
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
// Send the request to the engine, via the actor.
|
||||
self.engine_req_tx
|
||||
.send(ToEngineReq {
|
||||
req: final_req.clone(),
|
||||
req: WebSocketRequest::ModelingCmdReq {
|
||||
cmd: cmd.clone(),
|
||||
cmd_id: id,
|
||||
},
|
||||
request_sent: tx,
|
||||
})
|
||||
.await
|
||||
@ -310,7 +200,6 @@ impl EngineManager for EngineConnection {
|
||||
})
|
||||
})?;
|
||||
|
||||
|
||||
// Wait for the response.
|
||||
let current_time = std::time::Instant::now();
|
||||
while current_time.elapsed().as_secs() < 60 {
|
||||
@ -322,9 +211,8 @@ impl EngineManager for EngineConnection {
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((_, resp)) = self.responses.remove(&id_final) {
|
||||
println!("RESP {:?}", resp);
|
||||
// We pop off the responses to cleanup our mappings.
|
||||
if let Some((_, resp)) = self.responses.remove(&id) {
|
||||
return if let Some(data) = &resp.resp {
|
||||
Ok(data.clone())
|
||||
} else {
|
||||
@ -337,7 +225,7 @@ impl EngineManager for EngineConnection {
|
||||
}
|
||||
|
||||
Err(KclError::Engine(KclErrorDetails {
|
||||
message: format!("Modeling command timed out `{}`", id_final),
|
||||
message: format!("Modeling command timed out `{}`", id),
|
||||
source_ranges: vec![source_range],
|
||||
}))
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ impl EngineConnection {
|
||||
impl crate::engine::EngineManager for EngineConnection {
|
||||
async fn send_modeling_cmd(
|
||||
&self,
|
||||
_flush_batch: bool,
|
||||
_id: uuid::Uuid,
|
||||
_source_range: crate::executor::SourceRange,
|
||||
_cmd: kittycad::types::ModelingCmd,
|
||||
|
@ -13,7 +13,6 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
/// Send a modeling command and wait for the response message.
|
||||
async fn send_modeling_cmd(
|
||||
&self,
|
||||
flush_batch: bool,
|
||||
id: uuid::Uuid,
|
||||
source_range: crate::executor::SourceRange,
|
||||
cmd: kittycad::types::ModelingCmd,
|
||||
|
@ -1008,7 +1008,6 @@ pub async fn execute(
|
||||
// Before we even start executing the program, set the units.
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::SetSceneUnits {
|
||||
@ -1220,17 +1219,6 @@ pub async fn execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Fire the batch since we've reached the end.
|
||||
// ctx.engine
|
||||
// .send_modeling_cmd(
|
||||
// true,
|
||||
// uuid::Uuid::new_v4(),
|
||||
// SourceRange::default(),
|
||||
// // This is ignored when flush_batch is true.
|
||||
// kittycad::types::ModelingCmd::EditModeExit {},
|
||||
// )
|
||||
// .await?;
|
||||
|
||||
Ok(memory.clone())
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ impl Args {
|
||||
id: uuid::Uuid,
|
||||
cmd: kittycad::types::ModelingCmd,
|
||||
) -> Result<OkWebSocketResponseData, KclError> {
|
||||
self.ctx.engine.send_modeling_cmd(false, id, self.source_range, cmd).await
|
||||
self.ctx.engine.send_modeling_cmd(id, self.source_range, cmd).await
|
||||
}
|
||||
|
||||
fn make_user_val_from_json(&self, j: serde_json::Value) -> Result<MemoryItem, KclError> {
|
||||
|
3
src/wasm-lib/prelude.kcl
Normal file
3
src/wasm-lib/prelude.kcl
Normal file
@ -0,0 +1,3 @@
|
||||
fn hey_from_one_of_the_devs_of_the_past_i_wish_you_a_great_day_and_maybe_gave_you_a_little_smile_as_youve_found_this = () => {
|
||||
return 42
|
||||
}
|
@ -21,9 +21,9 @@ async fn execute_and_snapshot(code: &str, units: kittycad::types::UnitLength) ->
|
||||
let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
|
||||
|
||||
// Create the client.
|
||||
let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
|
||||
let client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
|
||||
// uncomment to use a local server
|
||||
client.set_base_url("http://localhost:8080/");
|
||||
//client.set_base_url("http://system76-pc:8080/");
|
||||
|
||||
let ws = client
|
||||
.modeling()
|
||||
@ -45,7 +45,6 @@ async fn execute_and_snapshot(code: &str, units: kittycad::types::UnitLength) ->
|
||||
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
kcl_lib::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::DefaultCameraLookAt {
|
||||
@ -61,7 +60,6 @@ async fn execute_and_snapshot(code: &str, units: kittycad::types::UnitLength) ->
|
||||
let resp = ctx
|
||||
.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
kcl_lib::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::TakeSnapshot {
|
||||
|
@ -49,7 +49,6 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, uuid
|
||||
let plane_id = uuid::Uuid::new_v4();
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
plane_id,
|
||||
SourceRange::default(),
|
||||
ModelingCmd::MakePlane {
|
||||
@ -68,7 +67,6 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, uuid
|
||||
// You can however get path info without sketch mode.
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
SourceRange::default(),
|
||||
ModelingCmd::SketchModeEnable {
|
||||
@ -84,7 +82,6 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, uuid
|
||||
// We can't get control points of an existing sketch without being in edit mode.
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
false,
|
||||
uuid::Uuid::new_v4(),
|
||||
SourceRange::default(),
|
||||
ModelingCmd::EditModeEnter { target: sketch_id },
|
||||
|
Reference in New Issue
Block a user