Skip to content

Commit

Permalink
fixups and logging (WIP)
Browse files Browse the repository at this point in the history
Signed-off-by: Nick Cameron <nrc@ncameron.org>
  • Loading branch information
nrc committed Feb 9, 2025
1 parent 96ff259 commit 0558fb0
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 39 deletions.
10 changes: 8 additions & 2 deletions src/clientSideScene/sceneEntities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,22 +688,28 @@ export class SceneEntities {
up: [number, number, number],
origin: [number, number, number]
) => {
console.log('updateAstAndRejigSketch 0 - getting back variables')
const nextAst = await kclManager.updateAst(modifiedAst, false)
console.log('updateAstAndRejigSketch 1')
await this.tearDownSketch({ removeAxis: false })
console.log('updateAstAndRejigSketch 2')
sceneInfra.resetMouseListeners()
console.log('updateAstAndRejigSketch 3 - getting error')
await this.setupSketch({
sketchPathToNode,
forward,
up,
position: origin,
maybeModdedAst: nextAst.newAst,
})
console.log('updateAstAndRejigSketch 4')
this.setupSketchIdleCallbacks({
forward,
up,
position: origin,
pathToNode: sketchPathToNode,
})
console.log('updateAstAndRejigSketch 5')
return nextAst
}
setupDraftSegment = async (
Expand Down Expand Up @@ -1853,7 +1859,7 @@ export class SceneEntities {
ast?: Node<Program>,
draftSegment?: DraftSegment
) =>
prepareTruncatedMemoryAndAst(
prepareTruncatedAst(
sketchPathToNode,
ast || kclManager.ast,
kclManager.lastSuccessfulVariables,
Expand Down Expand Up @@ -2365,7 +2371,7 @@ export class SceneEntities {

// calculations/pure-functions/easy to test so no excuse not to

function prepareTruncatedMemoryAndAst(
function prepareTruncatedAst(
sketchPathToNode: PathToNode,
ast: Node<Program>,
variables: VariableMap,
Expand Down
9 changes: 9 additions & 0 deletions src/components/ModelingMachineProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -889,16 +889,22 @@ export const ModelingMachineProvider = ({
await applyConstraintIntersect({
selectionRanges,
})
// TODO why parse and recast here?
console.log('mmp parse')
console.log(recast(modifiedAst))
const pResult = parse(recast(modifiedAst))
if (trap(pResult) || !resultIsOk(pResult))
return Promise.reject(new Error('Unexpected compilation error'))
const _modifiedAst = pResult.program
console.log('after mmp parse', recast(_modifiedAst))
if (!sketchDetails)
return Promise.reject(new Error('No sketch details'))
console.log('before calling updatePathToNodeFromMap')
const updatedPathToNode = updatePathToNodeFromMap(
sketchDetails.sketchPathToNode,
pathToNodeMap
)
console.log('before calling updateAstAndRejigSketch')
const updatedAst =
await sceneEntitiesManager.updateAstAndRejigSketch(
updatedPathToNode,
Expand All @@ -908,16 +914,19 @@ export const ModelingMachineProvider = ({
sketchDetails.origin
)
if (err(updatedAst)) return Promise.reject(updatedAst)
console.log('after calling updateAstAndRejigSketch')

await codeManager.updateEditorWithAstAndWriteToFile(
updatedAst.newAst
)
console.log('after calling updateEditorWithAstAndWriteToFile')

const selection = updateSelections(
pathToNodeMap,
selectionRanges,
updatedAst.newAst
)
console.log('after calling updateSelections')
if (err(selection)) return Promise.reject(selection)
return {
selectionType: 'completeSelection',
Expand Down
2 changes: 2 additions & 0 deletions src/components/Toolbar/Intersect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export async function applyConstraintIntersect({
transform2

if (variableName) {
console.log('create var', variableName)
const newBody = [..._modifiedAst.body]
newBody.splice(
newVariableInsertIndex,
Expand All @@ -205,6 +206,7 @@ export async function applyConstraintIntersect({
pathToNode[index][0] = Number(pathToNode[index][0]) + 1
})
}
console.log('all good')
return {
modifiedAst: _modifiedAst,
pathToNodeMap: _pathToNodeMap,
Expand Down
3 changes: 3 additions & 0 deletions src/lang/KclSingleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class KclManager {
startNodes: [],
},
}
// TODO why do we have so many copies of variables from execution?
private _execState: ExecState = emptyExecState()
private _variables: VariableMap = {}
lastSuccessfulVariables: VariableMap = {}
Expand Down Expand Up @@ -446,12 +447,14 @@ export class KclManager {
engineCommandManager: this.engineCommandManager,
isMock: true,
})
console.log('executeAstMock', execState.variables, errors)

this._logs = logs
this.addDiagnostics(kclErrorsToDiagnostics(errors))
this._execState = execState
this._variables = execState.variables
if (!errors.length) {
console.log('set last success')
this.lastSuccessfulVariables = execState.variables
this.lastSuccessfulOperations = execState.operations
}
Expand Down
1 change: 1 addition & 0 deletions src/lang/std/sketchcombos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,7 @@ export function transformSecondarySketchLinesTagFirst({
}
| Error {
// let node = structuredClone(ast)
console.log('transformSecondarySketchLinesTagFirst', memVars)

// We need to sort the selections by their start position
// so that we can process them in dependency order and not write invalid KCL.
Expand Down
17 changes: 15 additions & 2 deletions src/lang/wasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ function execStateFromRust(
artifact.codeRef.pathToNode = pathToNode
}

console.log(execOutcome.variables)
return {
variables: execOutcome.variables,
operations: execOutcome.operations,
Expand All @@ -339,6 +340,16 @@ function execStateFromRust(
}
}

function mockExecStateFromRust(execOutcome: RustExecOutcome): ExecState {
return {
variables: execOutcome.variables,
operations: execOutcome.operations,
artifacts: execOutcome.artifacts,
artifactCommands: execOutcome.artifactCommands,
artifactGraph: new Map<ArtifactId, Artifact>(),
}
}

export type ArtifactGraph = Map<ArtifactId, Artifact>

function rustArtifactGraphToMap(
Expand Down Expand Up @@ -419,15 +430,17 @@ export const executor = async (
if (!variables) {
variables = {}
}
console.log('wasm mock', variables)
const execOutcome: RustExecOutcome = await execute_mock(
JSON.stringify(node),
path,
JSON.stringify({ settings: jsAppSettings }),
JSON.stringify(variables),
fileSystemManager
)
return execStateFromRust(execOutcome, node)
return mockExecStateFromRust(execOutcome)
} else {
console.log('wasm full')
const execOutcome: RustExecOutcome = await execute_all(
JSON.stringify(node),
path,
Expand All @@ -438,7 +451,7 @@ export const executor = async (
return execStateFromRust(execOutcome, node)
}
} catch (e: any) {
console.log(e)
console.log('execute error', e)
const parsed: KclErrorWithOutputs = JSON.parse(e.toString())
const kclError = new KCLError(
parsed.error.kind,
Expand Down
21 changes: 0 additions & 21 deletions src/wasm-lib/kcl/src/execution/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,27 +569,6 @@ impl Solid {
}
}

/// An solid ID and its fillet and chamfer IDs. This is needed for lazy
/// fillet evaluation.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct SolidLazyIds {
pub solid_id: uuid::Uuid,
pub sketch_id: uuid::Uuid,
/// Chamfers or fillets on this solid.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub edge_cuts: Vec<uuid::Uuid>,
}

impl From<&Solid> for SolidLazyIds {
fn from(eg: &Solid) -> Self {
Self {
solid_id: eg.id,
sketch_id: eg.sketch.id,
edge_cuts: eg.edge_cuts.iter().map(|foc| foc.id()).collect(),
}
}
}

/// A fillet or a chamfer.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
Expand Down
37 changes: 37 additions & 0 deletions src/wasm-lib/kcl/src/execution/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,33 @@ impl ProgramMemory {
old
}

/// Pops the current frame of the call stack and merges it with the next frame.
///
/// Precondition: there are no snapshots of the current env.
pub fn squash_current_env(&mut self) {
let old = self.current_env;
self.current_env = self.call_stack.pop().unwrap();

if old.is_rust_env() {
return;
}

Check warning on line 295 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L289-L295

Added lines #L289 - L295 were not covered by tests

let mut old_env = if old.index() == self.environments.len() - 1 {

Check warning on line 297 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L297

Added line #L297 was not covered by tests
// Common case and efficient
self.environments.pop().unwrap()

Check warning on line 299 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L299

Added line #L299 was not covered by tests
} else {
// Should basically never happen in normal usage.
let cloned = self.environments[old.index()].clone();
self.environments[old.index()] = Environment::new(self.current_env);
cloned

Check warning on line 304 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L302-L304

Added lines #L302 - L304 were not covered by tests
};

// Move the variables in the popped env into the current env.
for (k, v) in old_env.take_bindings() {
self.environments[self.current_env.index()].insert_or_update(k.clone(), v.clone());
}
}

Check warning on line 311 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L308-L311

Added lines #L308 - L311 were not covered by tests

/// Snapshot the current state of the memory.
pub fn snapshot(&mut self) -> EnvironmentRef {
self.stats.snapshot_count += 1;
Expand Down Expand Up @@ -703,6 +730,16 @@ mod env {
) -> impl Iterator<Item = (&'a String, &'a KclValue)> {
self.bindings.iter().filter(move |(_, v)| f(v))
}

/// Take all bindings from the environment.
///
/// Precondition: no snapshots (since we don't take snapshots into account, if any exist
/// then the returned values may be incorrect).
pub(super) fn take_bindings(&mut self) -> impl Iterator<Item = (String, KclValue)> {
assert!(self.snapshots.is_empty(), "Snapshots exist of current env which means that taking the bindings will be inaccurate. Did you create a fn decl in the env?");
let bindings = std::mem::take(&mut self.bindings);
bindings.into_iter()
}

Check warning on line 742 in src/wasm-lib/kcl/src/execution/memory.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/memory.rs#L738-L742

Added lines #L738 - L742 were not covered by tests
}

impl Snapshot {
Expand Down
26 changes: 12 additions & 14 deletions src/wasm-lib/kcl/src/execution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,31 +535,29 @@ impl ExecutorContext {
let old_mem = cache::read_old_memory().await;
let mut mem = old_mem.unwrap_or_else(ProgramMemory::new);

Check warning on line 536 in src/wasm-lib/kcl/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/mod.rs#L535-L536

Added lines #L535 - L536 were not covered by tests

// Add any extra variables to memory
for (k, v) in variables {
crate::log::log(format!("add var: {k}"));
mem.add(&k, v, SourceRange::synthetic())
.map_err(KclErrorWithOutputs::no_outputs)?;

Check warning on line 542 in src/wasm-lib/kcl/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/mod.rs#L539-L542

Added lines #L539 - L542 were not covered by tests
}

// Push a scope so that old variables can be overwritten (since we might be re-executing some
// part of the scene).
mem.push_new_env_for_scope();

*exec_state.mut_memory() = mem;

Check warning on line 549 in src/wasm-lib/kcl/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/mod.rs#L547-L549

Added lines #L547 - L549 were not covered by tests
self.inner_run(&program.ast, &mut exec_state).await?;

// TODO remove
// let vars: Vec<_> = exec_state
// .memory()
// .find_all_in_current_env(|_| true)
// .map(|(k, v)| (k.clone(), v.clone()))
// .collect();
// Write any variables created in the run back to memory in case another run wants to use
// them.
let mut mem = exec_state.memory().clone();
mem.squash_current_env();
cache::write_old_memory(mem).await;

Check warning on line 556 in src/wasm-lib/kcl/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/mod.rs#L554-L556

Added lines #L554 - L556 were not covered by tests

// let mut mem = exec_state.memory().clone();
// mem.pop_env();
// for (k, v) in vars {
// mem.insert_or_update(k, v);
// }
// cache::write_old_memory(mem).await;

Ok(exec_state.to_wasm_outcome())
let outcome = exec_state.to_mock_wasm_outcome();
crate::log::log(format!("return mock {:#?}", outcome.variables));
Ok(outcome)

Check warning on line 560 in src/wasm-lib/kcl/src/execution/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/mod.rs#L558-L560

Added lines #L558 - L560 were not covered by tests
}

pub async fn run_with_caching(&self, program: crate::Program) -> Result<ExecOutcome, KclErrorWithOutputs> {
Expand Down
16 changes: 16 additions & 0 deletions src/wasm-lib/kcl/src/execution/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ impl ExecState {
}
}

pub fn to_mock_wasm_outcome(self) -> ExecOutcome {
// Fields are opt-in so that we don't accidentally leak private internal
// state when we add more to ExecState.
ExecOutcome {
variables: self
.memory()
.find_all_in_current_env(|_| true)
.map(|(k, v)| (k.clone(), v.clone()))
.collect(),
operations: Default::default(),
artifacts: Default::default(),
artifact_commands: Default::default(),
artifact_graph: Default::default(),
}
}

Check warning on line 128 in src/wasm-lib/kcl/src/execution/state.rs

View check run for this annotation

Codecov / codecov/patch

src/wasm-lib/kcl/src/execution/state.rs#L114-L128

Added lines #L114 - L128 were not covered by tests

pub fn memory(&self) -> &ProgramMemory {
&self.global.memory
}
Expand Down
3 changes: 3 additions & 0 deletions src/wasm-lib/kcl/src/std/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ impl Args {
exec_state: &mut ExecState,
solids: Vec<Box<Solid>>,
) -> Result<(), KclError> {
crate::log::log("flush_batch_for_solid_set");
// Make sure we don't traverse sketches more than once.
let mut traversed_sketches = Vec::new();

Expand All @@ -251,6 +252,7 @@ impl Args {
// We need to traverse the solids that share the same sketch.
let sketch_id = solid.sketch.id;
if !traversed_sketches.contains(&sketch_id) {
crate::log::log("solid");
// Find all the solids on the same shared sketch.
ids.extend(
exec_state
Expand All @@ -268,6 +270,7 @@ impl Args {
ids.extend(solid.get_all_edge_cut_ids());
}

crate::log::log(format!("flush_batch_for_solid_set {} {ids:#?}", ids.len()));
// We can return early if there are no fillets or chamfers.
if ids.is_empty() {
return Ok(());
Expand Down

0 comments on commit 0558fb0

Please sign in to comment.