deterministic id generator per module (#5811)

* deterministic id generator per module

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

* non

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

* updates

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

* do not remake the planes if they are alreaady made;

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

* updates

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

* do not remake the planes if they are alreaady made;

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

* clippy

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

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2025-03-15 10:08:39 -07:00
committed by GitHub
parent 9c986d3aa8
commit 3f02bb2065
86 changed files with 955 additions and 918 deletions

View File

@ -10,6 +10,7 @@ use cache::OldAstState;
pub use cache::{bust_cache, clear_mem_cache};
pub use cad_op::Operation;
pub use geometry::*;
pub use id_generator::IdGenerator;
pub(crate) use import::{
import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM,
};
@ -25,7 +26,7 @@ use kittycad_modeling_cmds as kcmc;
pub use memory::EnvironmentRef;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
pub use state::{ExecState, IdGenerator, MetaSettings};
pub use state::{ExecState, MetaSettings};
use crate::{
engine::EngineManager,
@ -49,6 +50,7 @@ pub(crate) mod cache;
mod cad_op;
mod exec_ast;
mod geometry;
mod id_generator;
mod import;
pub(crate) mod kcl_value;
mod memory;
@ -72,6 +74,8 @@ pub struct ExecOutcome {
pub errors: Vec<CompilationError>,
/// File Names in module Id array index order
pub filenames: IndexMap<ModuleId, ModulePath>,
/// The default planes.
pub default_planes: Option<DefaultPlanes>,
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
@ -367,22 +371,14 @@ impl ExecutorContext {
}
#[cfg(target_arch = "wasm32")]
pub async fn new(
engine_manager: crate::engine::conn_wasm::EngineCommandManager,
fs_manager: crate::fs::wasm::FileSystemManager,
settings: ExecutorSettings,
) -> Result<Self, String> {
Ok(ExecutorContext {
engine: Arc::new(Box::new(
crate::engine::conn_wasm::EngineConnection::new(engine_manager)
.await
.map_err(|e| format!("{:?}", e))?,
)),
fs: Arc::new(FileManager::new(fs_manager)),
pub fn new(engine: Arc<Box<dyn EngineManager>>, fs: Arc<FileManager>, settings: ExecutorSettings) -> Self {
ExecutorContext {
engine,
fs,
stdlib: Arc::new(StdLib::new()),
settings,
context_type: ContextType::Live,
})
}
}
#[cfg(not(target_arch = "wasm32"))]
@ -499,7 +495,7 @@ impl ExecutorContext {
source_range: crate::execution::SourceRange,
) -> Result<(), KclError> {
self.engine
.clear_scene(&mut exec_state.global.id_generator, source_range)
.clear_scene(&mut exec_state.mod_local.id_generator, source_range)
.await
}
@ -518,7 +514,7 @@ impl ExecutorContext {
) -> Result<ExecOutcome, KclErrorWithOutputs> {
assert!(self.is_mock());
let mut exec_state = ExecState::new(&self.settings);
let mut exec_state = ExecState::new(self);
if use_prev_memory {
match cache::read_old_memory().await {
Some(mem) => *exec_state.mut_stack() = mem,
@ -539,7 +535,7 @@ impl ExecutorContext {
// memory, not to the exec_state which is not cached for mock execution.
let mut mem = exec_state.stack().clone();
let outcome = exec_state.to_mock_wasm_outcome(result.0);
let outcome = exec_state.to_mock_wasm_outcome(result.0).await;
mem.squash_env(result.0);
cache::write_old_memory(mem).await;
@ -607,13 +603,13 @@ impl ExecutorContext {
})
.await;
let outcome = old_state.to_wasm_outcome(result_env);
let outcome = old_state.to_wasm_outcome(result_env).await;
return Ok(outcome);
}
(true, program)
}
CacheResult::NoAction(false) => {
let outcome = old_state.to_wasm_outcome(result_env);
let outcome = old_state.to_wasm_outcome(result_env).await;
return Ok(outcome);
}
};
@ -621,7 +617,7 @@ impl ExecutorContext {
let (exec_state, preserve_mem) = if clear_scene {
// Pop the execution state, since we are starting fresh.
let mut exec_state = old_state;
exec_state.reset(&self.settings);
exec_state.reset(self);
// We don't do this in mock mode since there is no engine connection
// anyways and from the TS side we override memory and don't want to clear it.
@ -638,7 +634,7 @@ impl ExecutorContext {
(program, exec_state, preserve_mem)
} else {
let mut exec_state = ExecState::new(&self.settings);
let mut exec_state = ExecState::new(self);
self.send_clear_scene(&mut exec_state, Default::default())
.await
.map_err(KclErrorWithOutputs::no_outputs)?;
@ -663,7 +659,7 @@ impl ExecutorContext {
})
.await;
let outcome = exec_state.to_wasm_outcome(result.0);
let outcome = exec_state.to_wasm_outcome(result.0).await;
Ok(outcome)
}
@ -699,6 +695,7 @@ impl ExecutorContext {
.await
.map_err(KclErrorWithOutputs::no_outputs)?;
let default_planes = self.engine.get_default_planes().read().await.clone();
let env_ref = self
.execute_and_build_graph(&program.ast, exec_state, preserve_mem)
.await
@ -717,6 +714,7 @@ impl ExecutorContext {
exec_state.global.artifact_graph.clone(),
module_id_to_module_path,
exec_state.global.id_to_source.clone(),
default_planes,
)
})?;
@ -754,6 +752,7 @@ impl ExecutorContext {
exec_state,
ExecutionKind::Normal,
preserve_mem,
ModuleId::default(),
&ModulePath::Main,
)
.await;
@ -933,7 +932,7 @@ pub(crate) async fn parse_execute(code: &str) -> Result<ExecTestResults, KclErro
settings: Default::default(),
context_type: ContextType::Mock,
};
let mut exec_state = ExecState::new(&exec_ctxt.settings);
let mut exec_state = ExecState::new(&exec_ctxt);
let result = exec_ctxt.run(&program, &mut exec_state).await?;
Ok(ExecTestResults {
@ -1880,10 +1879,14 @@ let w = f() + f()
let old_program = crate::Program::parse_no_errs(code).unwrap();
// Execute the program.
ctx.run_with_caching(old_program).await.unwrap();
if let Err(err) = ctx.run_with_caching(old_program).await {
let report = err.into_miette_report_with_outputs(code).unwrap();
let report = miette::Report::new(report);
panic!("Error executing program: {:?}", report);
}
// Get the id_generator from the first execution.
let id_generator = cache::read_old_ast().await.unwrap().exec_state.global.id_generator;
let id_generator = cache::read_old_ast().await.unwrap().exec_state.mod_local.id_generator;
let code = r#"sketch001 = startSketchOn(XZ)
|> startProfileAt([62.74, 206.13], %)
@ -1904,7 +1907,7 @@ let w = f() + f()
// Execute the program.
ctx.run_with_caching(program).await.unwrap();
let new_id_generator = cache::read_old_ast().await.unwrap().exec_state.global.id_generator;
let new_id_generator = cache::read_old_ast().await.unwrap().exec_state.mod_local.id_generator;
assert_eq!(id_generator, new_id_generator);
}
@ -1933,7 +1936,6 @@ let w = f() + f()
// Execute the program.
ctx.run_with_caching(old_program.clone()).await.unwrap();
// Get the id_generator from the first execution.
let settings_state = cache::read_old_ast().await.unwrap().settings;
// Ensure the settings are as expected.
@ -1945,7 +1947,6 @@ let w = f() + f()
// Execute the program.
ctx.run_with_caching(old_program.clone()).await.unwrap();
// Get the id_generator from the first execution.
let settings_state = cache::read_old_ast().await.unwrap().settings;
// Ensure the settings are as expected.
@ -1957,7 +1958,6 @@ let w = f() + f()
// Execute the program.
ctx.run_with_caching(old_program).await.unwrap();
// Get the id_generator from the first execution.
let settings_state = cache::read_old_ast().await.unwrap().settings;
// Ensure the settings are as expected.