From 62340775d147d05a321e8b258883ec878e2d2a66 Mon Sep 17 00:00:00 2001 From: Rn86222 Date: Thu, 22 May 2025 23:11:06 +0900 Subject: [PATCH 1/4] fix intrinsics evaluation --- src/store/intrinsics/definitions.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/store/intrinsics/definitions.ts b/src/store/intrinsics/definitions.ts index 9fdac6e..67edb95 100644 --- a/src/store/intrinsics/definitions.ts +++ b/src/store/intrinsics/definitions.ts @@ -23,7 +23,7 @@ function createUnaryOperator( evaluate: (input) => { invariant(input.A[0] && !input.A[1]); const A = input.A[0]; - return A.map((a) => [evaluate(nullthrows(a))]); + return [A.map((a) => evaluate(nullthrows(a)))]; }, }); } @@ -47,9 +47,11 @@ function createBinaryOperator( const A = input.A[0]; const B = input.B[0]; invariant(A.length === B.length); - return Array.from({ length: input.A.length }, (_, i) => [ - evaluate(nullthrows(A[i]), nullthrows(B[i])), - ]); + return [ + Array.from({ length: A.length }, (_, i) => + evaluate(nullthrows(A[i]), nullthrows(B[i])), + ), + ]; }, }); } @@ -123,10 +125,11 @@ export const broadcast = new IntrinsicComponentDefinition({ out: { name: "Out", isBitWidthConfigurable: true }, evaluate: (input, outputShape) => { invariant(input.In[0] && !input.In[1]); - const inputValue = input.In[0]; + invariant(input.In[0][0] !== undefined && !input.In[0][1]); + const inputValue = input.In[0][0]; invariant(outputShape[0] && !outputShape[1]); const outputMultiplicity = outputShape[0].multiplicity; - return Array.from({ length: outputMultiplicity }, () => inputValue); + return [Array.from({ length: outputMultiplicity }, () => inputValue)]; }, }); From 8acb36f94c000b73b11c0403e5caee2aaa099c24 Mon Sep 17 00:00:00 2001 From: Rn86222 Date: Thu, 22 May 2025 23:12:29 +0900 Subject: [PATCH 2/4] fix target of pointerDownEvent --- src/pages/edit/Editor/renderer/Background.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/edit/Editor/renderer/Background.tsx b/src/pages/edit/Editor/renderer/Background.tsx index 2cf0032..7dd3b1c 100644 --- a/src/pages/edit/Editor/renderer/Background.tsx +++ b/src/pages/edit/Editor/renderer/Background.tsx @@ -16,9 +16,7 @@ export default function CCComponentEditorRendererBackground() { const startPerspective = componentEditorState.perspective; const startPoint = vector2.fromDomEvent(pointerDownEvent.nativeEvent); - pointerDownEvent.currentTarget.setPointerCapture( - pointerDownEvent.pointerId, - ); + currentTarget.setPointerCapture(pointerDownEvent.pointerId); const onPointerMove = (pointerMoveEvent: PointerEvent) => { const endPoint = vector2.fromDomEvent(pointerMoveEvent); componentEditorState.setPerspective({ @@ -35,9 +33,7 @@ export default function CCComponentEditorRendererBackground() { const onPointerUp = () => { currentTarget.removeEventListener("pointermove", onPointerMove); currentTarget.removeEventListener("pointerup", onPointerUp); - pointerDownEvent.currentTarget.releasePointerCapture( - pointerDownEvent.pointerId, - ); + currentTarget.releasePointerCapture(pointerDownEvent.pointerId); }; currentTarget.addEventListener("pointermove", onPointerMove); currentTarget.addEventListener("pointerup", onPointerUp); From 1615ce32a478ffceebc174376982ce38207359ac Mon Sep 17 00:00:00 2001 From: Rn86222 Date: Thu, 22 May 2025 23:19:33 +0900 Subject: [PATCH 3/4] update multiplexability handling to use getMultiplicity method --- src/store/componentEvaluator.ts | 4 +-- src/store/componentPin.ts | 50 +++++++++++++++++++++++++++++---- src/store/nodePin.ts | 5 +++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/store/componentEvaluator.ts b/src/store/componentEvaluator.ts index a04853f..d455238 100644 --- a/src/store/componentEvaluator.ts +++ b/src/store/componentEvaluator.ts @@ -34,7 +34,7 @@ function createInput( ); const bitWidth = multiplexability.isMultiplexable ? 1 - : multiplexability.multiplicity; + : multiplexability.getMultiplicity(nodePins); return Array(bitWidth).fill(false); }); input[key] = values; @@ -58,7 +58,7 @@ function createOutputShape( if (multiplexability.isMultiplexable) { return 1; } - return multiplexability.multiplicity; + return multiplexability.getMultiplicity(nodePins); }); const outputShape = multiplicity.map((multiplicity) => ({ multiplicity })); return outputShape; diff --git a/src/store/componentPin.ts b/src/store/componentPin.ts index b8682c1..ec5f177 100644 --- a/src/store/componentPin.ts +++ b/src/store/componentPin.ts @@ -15,7 +15,7 @@ import { or, xor, } from "./intrinsics/definitions"; -import type { CCNodePinId } from "./nodePin"; +import type { CCNodePin, CCNodePinId } from "./nodePin"; export type CCComponentPin = { readonly id: CCComponentPinId; @@ -47,7 +47,11 @@ export type CCPinImplementation = CCNodePinId | null; export type CCPinMultiplexability = | { isMultiplexable: true } - | { isMultiplexable: false; multiplicity: number }; + | { + isMultiplexable: false; + getMultiplicity: (nodePins: CCNodePin[]) => number; + }; +// | { isMultiplexable: false; multiplicity: number }; export type CCComponentPinMultiplexability = | CCPinMultiplexability @@ -264,16 +268,52 @@ export class CCComponentPinStore extends EventEmitter return "undecidable"; } case nullthrows(aggregate.outputPin.id): { - return "undecidable"; + const getMultiplicity = (nodePins: CCNodePin[]): number => { + const multiplicity = nodePins + .filter((pin) => { + const componentPin = this.#store.componentPins.get( + pin.componentPinId, + ); + invariant(componentPin); + return componentPin.type === "input"; + }) + .reduce((acc, pin) => { + invariant(pin.userSpecifiedBitWidth); + return acc + pin.userSpecifiedBitWidth; + }, 0); + return multiplicity; + }; + return { + isMultiplexable: false, + getMultiplicity, + }; } case nullthrows(decompose.outputPin.id): { return "undecidable"; } case nullthrows(decompose.inputPin.In.id): { - return "undecidable"; + const getMultiplicity = (nodePins: CCNodePin[]): number => { + const multiplicity = nodePins + .filter((pin) => { + const componentPin = this.#store.componentPins.get( + pin.componentPinId, + ); + invariant(componentPin); + return componentPin.type === "output"; + }) + .reduce((acc, pin) => { + invariant(pin.userSpecifiedBitWidth); + return acc + pin.userSpecifiedBitWidth; + }, 0); + return multiplicity; + }; + return { + isMultiplexable: false, + getMultiplicity, + }; } case nullthrows(broadcast.inputPin.In.id): { - return { isMultiplexable: false, multiplicity: 1 }; + return { isMultiplexable: false, getMultiplicity: () => 1 }; } case nullthrows(broadcast.outputPin.id): { return "undecidable"; diff --git a/src/store/nodePin.ts b/src/store/nodePin.ts index 87560b4..ae87ddd 100644 --- a/src/store/nodePin.ts +++ b/src/store/nodePin.ts @@ -194,7 +194,10 @@ export class CCNodePinStore extends EventEmitter { userSpecifiedBitWidth, "Multiplexability of undecidable pin must be contained in multiplexabilityEnv", ); - return { isMultiplexable: false, multiplicity: userSpecifiedBitWidth }; + return { + isMultiplexable: false, + getMultiplicity: () => userSpecifiedBitWidth, + }; } if (!givenPinMultiplexability.isMultiplexable) { return givenPinMultiplexability; From 096521c441bfdbe6065ebbe30129c594409c6e3c Mon Sep 17 00:00:00 2001 From: Rn86222 Date: Fri, 23 May 2025 01:11:25 +0900 Subject: [PATCH 4/4] update NodePin and component pin handling to use multiplicity directly --- src/pages/edit/Editor/renderer/NodePin.tsx | 6 +- .../edit/Editor/store/slices/core/index.ts | 16 ++++- .../edit/Editor/store/slices/core/types.ts | 7 ++- src/store/componentEvaluator.ts | 4 +- src/store/componentPin.ts | 63 +++++++++---------- src/store/nodePin.ts | 8 ++- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/pages/edit/Editor/renderer/NodePin.tsx b/src/pages/edit/Editor/renderer/NodePin.tsx index ffb4f4a..f825f9e 100644 --- a/src/pages/edit/Editor/renderer/NodePin.tsx +++ b/src/pages/edit/Editor/renderer/NodePin.tsx @@ -29,6 +29,7 @@ export default function CCComponentEditorRendererNodePin({ const componentEditorState = useComponentEditorStore()(); const nodePin = nullthrows(store.nodePins.get(nodePinId)); const node = nullthrows(store.nodes.get(nodePin.nodeId)); + const nodePins = store.nodePins.getManyByNodeId(node.id); const componentPin = nullthrows( store.componentPins.get(nodePin.componentPinId), ); @@ -152,7 +153,10 @@ export default function CCComponentEditorRendererNodePin({ implementationComponentPin.type === "input" ) { nodePinValue = nullthrows( - componentEditorState.getInputValue(implementationComponentPin.id), + componentEditorState.getInputValue( + implementationComponentPin.id, + nodePins, + ), ); } else { nodePinValue = nullthrows( diff --git a/src/pages/edit/Editor/store/slices/core/index.ts b/src/pages/edit/Editor/store/slices/core/index.ts index 88295d0..64828cf 100644 --- a/src/pages/edit/Editor/store/slices/core/index.ts +++ b/src/pages/edit/Editor/store/slices/core/index.ts @@ -5,7 +5,7 @@ import simulateComponent from "../../../../../../store/componentEvaluator"; import type { CCComponentPinId } from "../../../../../../store/componentPin"; import type { CCConnectionId } from "../../../../../../store/connection"; import type { CCNodeId } from "../../../../../../store/node"; -import type { CCNodePinId } from "../../../../../../store/nodePin"; +import type { CCNodePin, CCNodePinId } from "../../../../../../store/nodePin"; import type { ComponentEditorSliceCreator } from "../../types"; import type { EditorStoreCoreSlice } from "./types"; @@ -46,12 +46,13 @@ export const createComponentEditorStoreCoreSlice: ComponentEditorSliceCreator< }, /** @private */ inputValues: new Map(), - getInputValue(componentPinId: CCComponentPinId) { + getInputValue(componentPinId: CCComponentPinId, nodePins: CCNodePin[]) { const value = get().inputValues.get(componentPinId); if (!value) { const multiplexability = store.componentPins.getComponentPinMultiplexability( componentPinId, + nodePins, ); if (multiplexability === "undecidable") { throw new Error("Cannot determine multiplexability"); @@ -174,8 +175,17 @@ export const createComponentEditorStoreCoreSlice: ComponentEditorSliceCreator< const inputValues = new Map(); const pins = store.componentPins.getManyByComponentId(componentId); for (const pin of pins) { + invariant(pin.implementation); if (pin.type === "input") { - inputValues.set(pin.id, editorState.getInputValue(pin.id)); + const nodePin = store.nodePins.get(pin.implementation); + invariant(nodePin); + const node = store.nodes.get(nodePin.nodeId); + invariant(node); + const nodePins = store.nodePins.getManyByNodeId(node.id); + inputValues.set( + pin.id, + editorState.getInputValue(pin.id, nodePins), + ); } } simulationCachedFrames.push( diff --git a/src/pages/edit/Editor/store/slices/core/types.ts b/src/pages/edit/Editor/store/slices/core/types.ts index 052a3d1..e1e62d3 100644 --- a/src/pages/edit/Editor/store/slices/core/types.ts +++ b/src/pages/edit/Editor/store/slices/core/types.ts @@ -3,7 +3,7 @@ import type { Vector2 } from "../../../../../../common/vector2"; import type { CCComponentPinId } from "../../../../../../store/componentPin"; import type { CCConnectionId } from "../../../../../../store/connection"; import type { CCNodeId } from "../../../../../../store/node"; -import type { CCNodePinId } from "../../../../../../store/nodePin"; +import type { CCNodePin, CCNodePinId } from "../../../../../../store/nodePin"; export type EditorMode = EditorModeEdit | EditorModePlay; export type EditorModeEdit = "edit"; @@ -30,7 +30,10 @@ export type EditorStoreCoreSlice = { target: NodePinPropertyEditorTarget | null, ): void; inputValues: Map; - getInputValue(componentPinId: CCComponentPinId): SimulationValue; + getInputValue( + componentPinId: CCComponentPinId, + nodePins: CCNodePin[], + ): SimulationValue; setInputValue(componentPinId: CCComponentPinId, value: SimulationValue): void; setEditorMode(mode: EditorMode): void; resetTimeStep(): void; diff --git a/src/store/componentEvaluator.ts b/src/store/componentEvaluator.ts index d455238..a04853f 100644 --- a/src/store/componentEvaluator.ts +++ b/src/store/componentEvaluator.ts @@ -34,7 +34,7 @@ function createInput( ); const bitWidth = multiplexability.isMultiplexable ? 1 - : multiplexability.getMultiplicity(nodePins); + : multiplexability.multiplicity; return Array(bitWidth).fill(false); }); input[key] = values; @@ -58,7 +58,7 @@ function createOutputShape( if (multiplexability.isMultiplexable) { return 1; } - return multiplexability.getMultiplicity(nodePins); + return multiplexability.multiplicity; }); const outputShape = multiplicity.map((multiplicity) => ({ multiplicity })); return outputShape; diff --git a/src/store/componentPin.ts b/src/store/componentPin.ts index ec5f177..bd73670 100644 --- a/src/store/componentPin.ts +++ b/src/store/componentPin.ts @@ -49,7 +49,7 @@ export type CCPinMultiplexability = | { isMultiplexable: true } | { isMultiplexable: false; - getMultiplicity: (nodePins: CCNodePin[]) => number; + multiplicity: number; }; // | { isMultiplexable: false; multiplicity: number }; @@ -243,6 +243,7 @@ export class CCComponentPinStore extends EventEmitter */ getComponentPinMultiplexability( pinId: CCComponentPinId, + nodePins: CCNodePin[], ): CCComponentPinMultiplexability { const pin = this.#pins.get(pinId); invariant(pin); @@ -268,52 +269,46 @@ export class CCComponentPinStore extends EventEmitter return "undecidable"; } case nullthrows(aggregate.outputPin.id): { - const getMultiplicity = (nodePins: CCNodePin[]): number => { - const multiplicity = nodePins - .filter((pin) => { - const componentPin = this.#store.componentPins.get( - pin.componentPinId, - ); - invariant(componentPin); - return componentPin.type === "input"; - }) - .reduce((acc, pin) => { - invariant(pin.userSpecifiedBitWidth); - return acc + pin.userSpecifiedBitWidth; - }, 0); - return multiplicity; - }; + const multiplicity = nodePins + .filter((pin) => { + const componentPin = this.#store.componentPins.get( + pin.componentPinId, + ); + invariant(componentPin); + return componentPin.type === "input"; + }) + .reduce((acc, pin) => { + invariant(pin.userSpecifiedBitWidth); + return acc + pin.userSpecifiedBitWidth; + }, 0); return { isMultiplexable: false, - getMultiplicity, + multiplicity, }; } case nullthrows(decompose.outputPin.id): { return "undecidable"; } case nullthrows(decompose.inputPin.In.id): { - const getMultiplicity = (nodePins: CCNodePin[]): number => { - const multiplicity = nodePins - .filter((pin) => { - const componentPin = this.#store.componentPins.get( - pin.componentPinId, - ); - invariant(componentPin); - return componentPin.type === "output"; - }) - .reduce((acc, pin) => { - invariant(pin.userSpecifiedBitWidth); - return acc + pin.userSpecifiedBitWidth; - }, 0); - return multiplicity; - }; + const multiplicity = nodePins + .filter((pin) => { + const componentPin = this.#store.componentPins.get( + pin.componentPinId, + ); + invariant(componentPin); + return componentPin.type === "output"; + }) + .reduce((acc, pin) => { + invariant(pin.userSpecifiedBitWidth); + return acc + pin.userSpecifiedBitWidth; + }, 0); return { isMultiplexable: false, - getMultiplicity, + multiplicity, }; } case nullthrows(broadcast.inputPin.In.id): { - return { isMultiplexable: false, getMultiplicity: () => 1 }; + return { isMultiplexable: false, multiplicity: 1 }; } case nullthrows(broadcast.outputPin.id): { return "undecidable"; diff --git a/src/store/nodePin.ts b/src/store/nodePin.ts index ae87ddd..b3630f3 100644 --- a/src/store/nodePin.ts +++ b/src/store/nodePin.ts @@ -188,7 +188,10 @@ export class CCNodePinStore extends EventEmitter { const node = nullthrows(this.#store.nodes.get(nodeId)); const nodePins = this.getManyByNodeId(node.id); const givenPinMultiplexability = - this.#store.componentPins.getComponentPinMultiplexability(pinId); + this.#store.componentPins.getComponentPinMultiplexability( + pinId, + nodePins, + ); if (givenPinMultiplexability === "undecidable") { invariant( userSpecifiedBitWidth, @@ -196,7 +199,7 @@ export class CCNodePinStore extends EventEmitter { ); return { isMultiplexable: false, - getMultiplicity: () => userSpecifiedBitWidth, + multiplicity: userSpecifiedBitWidth, }; } if (!givenPinMultiplexability.isMultiplexable) { @@ -206,6 +209,7 @@ export class CCNodePinStore extends EventEmitter { const pinMultiplexability = this.#store.componentPins.getComponentPinMultiplexability( nodePin.componentPinId, + nodePins, ); if (pinMultiplexability === "undecidable") { throw new Error("unreachable");