Remove circular dependency, avoid adding 2 new ones

This commit is contained in:
Frank Noirot
2025-07-03 09:10:48 -04:00
parent 4b00d00977
commit 40388b80e7
13 changed files with 39 additions and 13 deletions

View File

@ -10,4 +10,3 @@
5) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts
6) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts
7) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts
8) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/setAngleLength.tsx -> src/components/SetAngleLengthModal.tsx -> src/lib/useCalculateKclExpression.ts

View File

@ -33,6 +33,7 @@ import { useSettings } from '@src/lib/singletons'
import { commandBarActor, useCommandBarState } from '@src/lib/singletons'
import styles from './CommandBarKclInput.module.css'
import { useModelingContext } from '@src/hooks/useModelingContext'
// TODO: remove the need for this selector once we decouple all actors from React
const machineContextSelector = (snapshot?: SnapshotFrom<AnyStateMachine>) =>
@ -55,6 +56,9 @@ function CommandBarKclInput({
arg.name
] as KclCommandValue | undefined
const settings = useSettings()
const {
context: { selectionRanges },
} = useModelingContext()
const argMachineContext = useSelector(
arg.machineActor,
machineContextSelector
@ -126,6 +130,7 @@ function CommandBarKclInput({
value,
initialVariableName,
sourceRange: sourceRangeForPrevVariables,
selectionRanges,
})
const varMentionData: Completion[] = prevVariables.map((v) => {

View File

@ -10,6 +10,7 @@ import {
} from '@src/components/AvailableVarsHelpers'
import type { Expr } from '@src/lang/wasm'
import { useCalculateKclExpression } from '@src/lib/useCalculateKclExpression'
import type { Selections } from '@src/lib/selections'
type ModalResolve = {
value: string
@ -25,6 +26,7 @@ type SetAngleLengthModalProps = InstanceProps<ModalResolve, ModalReject> & {
value: number
valueName: string
shouldCreateVariable?: boolean
selectionRanges: Selections
}
export const createSetAngleLengthModal = create<
@ -40,6 +42,7 @@ export const SetAngleLengthModal = ({
value: initialValue,
valueName,
shouldCreateVariable: initialShouldCreateVariable = false,
selectionRanges,
}: SetAngleLengthModalProps) => {
const [sign, setSign] = useState(Math.sign(Number(initialValue)))
const [value, setValue] = useState(String(initialValue * sign))
@ -59,6 +62,7 @@ export const SetAngleLengthModal = ({
} = useCalculateKclExpression({
value,
initialVariableName: valueName,
selectionRanges,
})
return (

View File

@ -10,6 +10,7 @@ import {
} from '@src/components/AvailableVarsHelpers'
import type { Expr } from '@src/lang/wasm'
import { useCalculateKclExpression } from '@src/lib/useCalculateKclExpression'
import type { Selections } from '@src/lib/selections'
type ModalResolve = {
value: string
@ -27,6 +28,7 @@ type GetInfoModalProps = InstanceProps<ModalResolve, ModalReject> & {
isSegNameEditable: boolean
value?: number
initialVariableName: string
selectionRanges: Selections
}
export const createInfoModal = create<
@ -43,6 +45,7 @@ export const GetInfoModal = ({
isSegNameEditable,
value: initialValue,
initialVariableName,
selectionRanges,
}: GetInfoModalProps) => {
const [sign, setSign] = useState(Math.sign(Number(initialValue)))
const [segName, setSegName] = useState(initialSegName)
@ -60,7 +63,11 @@ export const GetInfoModal = ({
newVariableName,
isNewVariableNameUnique,
newVariableInsertIndex,
} = useCalculateKclExpression({ value: value, initialVariableName })
} = useCalculateKclExpression({
value: value,
initialVariableName,
selectionRanges,
})
return (
<Transition appear show={isOpen} as={Fragment}>

View File

@ -6,11 +6,13 @@ import { type InstanceProps, create } from 'react-modal-promise'
import { ActionButton } from '@src/components/ActionButton'
import { CreateNewVariable } from '@src/components/AvailableVarsHelpers'
import { useCalculateKclExpression } from '@src/lib/useCalculateKclExpression'
import type { Selections } from '@src/lib/selections'
type ModalResolve = { variableName: string }
type ModalReject = boolean
type SetVarNameModalProps = InstanceProps<ModalResolve, ModalReject> & {
valueName: string
selectionRanges: Selections
}
export const createSetVarNameModal = create<
@ -24,9 +26,14 @@ export const SetVarNameModal = ({
onResolve,
onReject,
valueName,
selectionRanges,
}: SetVarNameModalProps) => {
const { isNewVariableNameUnique, newVariableName, setNewVariableName } =
useCalculateKclExpression({ value: '', initialVariableName: valueName })
useCalculateKclExpression({
value: '',
initialVariableName: valueName,
selectionRanges,
})
return (
<Transition appear show={isOpen} as={Fragment}>

View File

@ -1,5 +1,4 @@
import type { Node } from '@rust/kcl-lib/bindings/Node'
import { removeDoubleNegatives } from '@src/components/AvailableVarsHelpers'
import {
GetInfoModal,
@ -167,6 +166,7 @@ export async function applyConstraintIntersect({
isSegNameEditable: !tagInfo?.isTagExisting,
value: valueUsedInTransform,
initialVariableName: 'offset',
selectionRanges,
})
if (
!variableName &&

View File

@ -113,6 +113,7 @@ export async function applyConstraintAbsDistance({
await getModalInfo({
value: forceVal,
valueName: constraint === 'yAbs' ? 'yDis' : 'xDis',
selectionRanges,
})
if (!isExprBinaryPart(valueNode))
return Promise.reject('Invalid valueNode, is not a BinaryPart')

View File

@ -117,7 +117,8 @@ export async function applyConstraintAngleBetween({
isSegNameEditable: !tagInfo?.isTagExisting,
value: valueUsedInTransform,
initialVariableName: 'angle',
} as any)
selectionRanges,
})
if (
segName === tagInfo?.tag &&
Number(value) === valueUsedInTransform &&

View File

@ -123,7 +123,8 @@ export async function applyConstraintHorzVertDistance({
isSegNameEditable: !tagInfo?.isTagExisting,
value: valueUsedInTransform,
initialVariableName: constraint === 'setHorzDistance' ? 'xDis' : 'yDis',
} as any)
selectionRanges,
})
if (
!variableName &&
segName === tagInfo?.tag &&

View File

@ -143,6 +143,7 @@ export async function applyConstraintAngleLength({
value: forceVal,
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
shouldCreateVariable: true,
selectionRanges,
})
if (!isExprBinaryPart(valueNode))
return Promise.reject('Invalid valueNode, is not a BinaryPart')

View File

@ -52,6 +52,7 @@ export function useConvertToVariable(range?: SourceRange) {
try {
const { variableName } = await getVarNameModal({
valueName: valueName || 'var',
selectionRanges: context.selectionRanges,
})
const { modifiedAst: _modifiedAst, pathToReplacedNode } =

View File

@ -1,6 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useModelingContext } from '@src/hooks/useModelingContext'
import { useKclContext } from '@src/lang/KclProvider'
import { findUniqueName } from '@src/lang/create'
import type { PrevVariable } from '@src/lang/queryAst'
@ -12,6 +10,7 @@ import { getCalculatedKclExpressionValue } from '@src/lib/kclHelpers'
import { kclManager } from '@src/lib/singletons'
import { err } from '@src/lib/trap'
import { getInVariableCase } from '@src/lib/utils'
import type { Selections } from '@src/lib/selections'
const isValidVariableName = (name: string) =>
/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)
@ -25,10 +24,12 @@ export function useCalculateKclExpression({
value,
initialVariableName: valueName = '',
sourceRange,
selectionRanges,
}: {
value: string
initialVariableName?: string
sourceRange?: SourceRange
selectionRanges: Selections
}): {
inputRef: React.RefObject<HTMLInputElement>
valueNode: Expr | null
@ -45,12 +46,10 @@ export function useCalculateKclExpression({
// has completed
const [isExecuting, setIsExecuting] = useState(false)
const { variables, code } = useKclContext()
const { context } = useModelingContext()
// If there is no selection, use the end of the code
// so all variables are available
const selectionRange:
| (typeof context)['selectionRanges']['graphSelections'][number]['codeRef']['range']
| undefined = context.selectionRanges.graphSelections[0]?.codeRef?.range
const selectionRange: SourceRange | undefined =
selectionRanges.graphSelections[0]?.codeRef?.range
// If there is no selection, use the end of the code
// If we don't memoize this, we risk an infinite set/read state loop
const endingSourceRange = useMemo(

View File

@ -29,7 +29,6 @@ import {
applyConstraintHorzVert,
horzVertInfo,
} from '@src/components/Toolbar/HorzVert'
import { intersectInfo } from '@src/components/Toolbar/Intersect'
import {
applyRemoveConstrainingValues,
removeConstrainingValuesInfo,
@ -155,6 +154,7 @@ import type { Plane } from '@rust/kcl-lib/bindings/Plane'
import type { Point3d } from '@rust/kcl-lib/bindings/ModelingCmd'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import { letEngineAnimateAndSyncCamAfter } from '@src/clientSideScene/CameraControls'
import { intersectInfo } from '@src/components/Toolbar/Intersect'
export type SetSelections =
| {