Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 42 additions & 52 deletions src/pages/edit/Editor/components/NodePinPropertyEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CCConnectionStore } from "../../../../store/connection";
import { IntrinsicComponentDefinition } from "../../../../store/intrinsics/base";
import { CCNodePinStore } from "../../../../store/nodePin";
import { useStore } from "../../../../store/react";
import getCCComponentEditorRendererNodeGeometry from "../renderer/Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "../renderer/Node/geometry";
import { useComponentEditorStore } from "../store";

export function CCComponentEditorNodePinPropertyEditor() {
Expand Down Expand Up @@ -123,33 +123,22 @@ export function CCComponentEditorNodePinPropertyEditor() {
nodePin.id,
);
for (const connection of connections) {
const anotherNodePinId =
connection.from === nodePin.id
? connection.to
: connection.from;
const fromNodePinId =
connection.from === nodePin.id
? nodePin.id
: anotherNodePinId;
const toNodePinId =
connection.from === nodePin.id
? anotherNodePinId
: nodePin.id;
const from = connection.from;
const to = connection.to;
const parentComponentId = connection.parentComponentId;
store.connections.unregister([connection.id]);
if (
store.nodePins.isConnectable(nodePin.id, anotherNodePinId)
) {
// reconnect if still connectable after bit width change
store.connections.register(
CCConnectionStore.create({
parentComponentId,
from: fromNodePinId,
to: toNodePinId,
bentPortion: 0.5,
}),
);
}
store.connections.unregister([connection.id]).then(() => {
if (store.nodePins.isConnectable(from, to)) {
// reconnect if still connectable after bit width change
store.connections.register(
CCConnectionStore.create({
parentComponentId,
from,
to,
bentPortion: 0.5,
}),
);
}
});
}
}
continue;
Expand Down Expand Up @@ -180,31 +169,32 @@ export function CCComponentEditorNodePinPropertyEditor() {
})}
</Stack>
<Stack direction="row" gap={1} sx={{ mt: 1 }}>
{componentPinAttributes.isSplittable && (
<>
<Button
type="button"
variant="outlined"
size="small"
onClick={() => {
setNewBitWidthList([...bitWidthList, 1]);
}}
>
Add
</Button>
<Button
type="button"
variant="outlined"
size="small"
disabled={bitWidthList.length <= 1}
onClick={() => {
setNewBitWidthList(bitWidthList.slice(0, -1));
}}
>
Remove
</Button>
</>
)}
{componentPinAttributes.bitWidthPolicy.type === "configurable" &&
componentPinAttributes.bitWidthPolicy.isSplittable && (
<>
<Button
type="button"
variant="outlined"
size="small"
onClick={() => {
setNewBitWidthList([...bitWidthList, 1]);
}}
>
Add
</Button>
<Button
type="button"
variant="outlined"
size="small"
disabled={bitWidthList.length <= 1}
onClick={() => {
setNewBitWidthList(bitWidthList.slice(0, -1));
}}
>
Remove
</Button>
</>
)}
<Button
type="submit"
variant="contained"
Expand Down
3 changes: 3 additions & 0 deletions src/pages/edit/Editor/components/ViewModeSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Edit, PlayArrow } from "@mui/icons-material";
import { Fab } from "@mui/material";
import { useCanSimulate } from "../../../../store/react/selectors";
import { useComponentEditorStore } from "../store";

export default function CCComponentEditorViewModeSwitcher() {
const componentEditorState = useComponentEditorStore()();
const canSimulate = useCanSimulate(componentEditorState.componentId);

return (
<Fab
Expand All @@ -15,6 +17,7 @@ export default function CCComponentEditorViewModeSwitcher() {
);
componentEditorState.setTimeStep(0);
}}
disabled={!canSimulate}
>
{componentEditorState.editorMode === "edit" ? <PlayArrow /> : <Edit />}
</Fab>
Expand Down
23 changes: 13 additions & 10 deletions src/pages/edit/Editor/renderer/ComponentPin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useStore } from "../../../../../store/react";
import { wrappingIncrementSimulationValue } from "../../../../../store/simulation";
import { useComponentEditorStore } from "../../store";
import { stringifySimulationValue } from "../../store/slices/core";
import getCCComponentEditorRendererNodeGeometry from "./../Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "./../Node/geometry";
export type CCComponentEditorRendererComponentPinProps = {
nodePinId: CCNodePinId;
};
Expand All @@ -30,24 +30,27 @@ export default function CCComponentEditorRendererComponentPin({
label: stringifySimulationValue(
type === "input"
? nullthrows(
componentEditorState.getInputValue([
interfaceComponentPin.id,
componentEditorState.timeStep,
]),
componentEditorState.getInputValue({
componentPinId: interfaceComponentPin.id,
timeStep: componentEditorState.timeStep,
}),
)
: nullthrows(componentEditorState.getNodePinValue(nodePinId)),
),
onClick:
type === "input"
? () => {
const nodePinValue = nullthrows(
componentEditorState.getInputValue([
interfaceComponentPin.id,
componentEditorState.timeStep,
]),
componentEditorState.getInputValue({
componentPinId: interfaceComponentPin.id,
timeStep: componentEditorState.timeStep,
}),
);
componentEditorState.setInputValue(
[interfaceComponentPin.id, componentEditorState.timeStep],
{
componentPinId: interfaceComponentPin.id,
timeStep: componentEditorState.timeStep,
},
wrappingIncrementSimulationValue(nodePinValue),
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/edit/Editor/renderer/Connection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ensureStoreItem from "../../../../../store/react/error";
import { useNode } from "../../../../../store/react/selectors";
import { useComponentEditorStore } from "../../store";
import { stringifySimulationValue } from "../../store/slices/core/index";
import getCCComponentEditorRendererNodeGeometry from "../Node/geometry";
import { getCCComponentEditorRendererNodeGeometry } from "../Node/geometry";

export type CCComponentEditorRendererConnectionEndpoint = {
direction: CCComponentPinType;
Expand Down
24 changes: 24 additions & 0 deletions src/pages/edit/Editor/renderer/Node/components/Const/geometry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import nullthrows from "nullthrows";
import { type Vector2, vector2 } from "../../../../../../../common/vector2";
import type { CCNodePinId } from "../../../../../../../store/nodePin";
import type {
CCComponentEditorRendererNodeLayout,
CCComponentEditorRendererNodeLayoutSource,
} from "../../types";

export const ccComponentEditorRendererNodeConstLayoutConstants = {
padding: 8,
gridSize: 12,
gridSizeDisplayWidth: 60,
};

export function ccComponentRendererNodeConstLayoutCalculator(
source: CCComponentEditorRendererNodeLayoutSource,
): CCComponentEditorRendererNodeLayout {
return {
size: vector2.create(400, 100),
nodePinOffsetById: new Map<CCNodePinId, Vector2>([
[nullthrows(source.outputNodePinIds[0]), vector2.create(400, 50)],
]),
};
}
59 changes: 59 additions & 0 deletions src/pages/edit/Editor/renderer/Node/components/Const/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useMemo } from "react";
import type { CCIntrinsicComponentConstSpec } from "../../../../../../../store/intrinsics/types";
import type { CCComponentEditorRendererNodeRendererProps } from "../../types";
import { CCComponentEditorRendererNodeDefaultRenderer } from "../Default";
import { ccComponentEditorRendererNodeConstLayoutConstants as constants } from "./geometry";

export function CCComponentEditorRendererNodeConstRenderer(
props: CCComponentEditorRendererNodeRendererProps,
) {
const config = props.node.config as CCIntrinsicComponentConstSpec["config"];
const sampleData = useMemo(
() => Array.from({ length: config.data.length }, () => Math.random() < 0.5),
[config.data],
);

return (
<>
<CCComponentEditorRendererNodeDefaultRenderer {...props} />
<foreignObject
x={constants.padding}
y={constants.padding}
width={props.geometry.rect.size.x - constants.padding * 2}
height={props.geometry.rect.size.y - constants.padding * 2}
>
<table>
<tbody>
{Array(Math.ceil(config.data.length / 8))
.fill(null)
.map((_, rowIndex) => (
// biome-ignore lint/suspicious/noArrayIndexKey: temporary workaround
<tr key={rowIndex}>
{Array(8)
.fill(null)
.map((_, colIndex) => {
const index = rowIndex * 8 + colIndex;
if (index >= config.data.length) return null;
return (
<td
// biome-ignore lint/suspicious/noArrayIndexKey: temporary workaround
key={colIndex}
style={{
width: constants.gridSize,
height: constants.gridSize,
backgroundColor: sampleData[index]
? "black"
: "white",
border: "1px solid black",
}}
/>
);
})}
</tr>
))}
</tbody>
</table>
</foreignObject>
</>
);
}
71 changes: 31 additions & 40 deletions src/pages/edit/Editor/renderer/Node/components/Default/geometry.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
import { type Vector2, vector2 } from "../../../../../../../common/vector2";
import type { Vector2 } from "../../../../../../../common/vector2";
import type { CCNodePinId } from "../../../../../../../store/nodePin";
import type {
CCComponentEditorRendererNodeGeometryCalculator,
CCComponentEditorRendererNodeGeometrySource,
CCComponentEditorRendererNodeLayout,
CCComponentEditorRendererNodeLayoutSource,
} from "../../types";

const width = 100;
const gapY = 20;
const paddingY = 15;

export const ccComponentRendererNodeDefaultGeometryCalculator: CCComponentEditorRendererNodeGeometryCalculator =
(source: CCComponentEditorRendererNodeGeometrySource) => {
const size: Vector2 = {
x: width,
y:
gapY *
Math.max(
source.inputNodePinIds.length,
source.outputNodePinIds.length,
) +
paddingY * 2,
};
export function ccComponentRendererNodeDefaultLayoutCalculator(
source: CCComponentEditorRendererNodeLayoutSource,
): CCComponentEditorRendererNodeLayout {
const size: Vector2 = {
x: width,
y:
gapY *
Math.max(
source.inputNodePinIds.length,
source.outputNodePinIds.length,
) +
paddingY * 2,
};

const nodePinPositionById = new Map<CCNodePinId, Vector2>();
for (const [index, nodePinId] of source.inputNodePinIds.entries()) {
nodePinPositionById.set(nodePinId, {
x: source.position.x - size.x / 2,
y:
source.position.y +
gapY * (index - source.inputNodePinIds.length / 2 + 0.5),
});
}
for (const [index, nodePinId] of source.outputNodePinIds.entries()) {
nodePinPositionById.set(nodePinId, {
x: source.position.x + size.x / 2,
y:
source.position.y +
gapY * (index - source.outputNodePinIds.length / 2 + 0.5),
});
}
const nodePinOffsetById = new Map<CCNodePinId, Vector2>();

return {
rect: {
position: vector2.sub(source.position, vector2.div(size, 2)),
size,
},
nodePinPositionById,
};
};
const startYIn =
size.y / 2 - (gapY * (source.inputNodePinIds.length - 1)) / 2;
for (const [index, pinId] of source.inputNodePinIds.entries()) {
nodePinOffsetById.set(pinId, { x: 0, y: startYIn + gapY * index });
}

const startYOut =
size.y / 2 - (gapY * (source.outputNodePinIds.length - 1)) / 2;
for (const [index, pinId] of source.outputNodePinIds.entries()) {
nodePinOffsetById.set(pinId, { x: size.x, y: startYOut + gapY * index });
}

return { size, nodePinOffsetById };
}
12 changes: 6 additions & 6 deletions src/pages/edit/Editor/renderer/Node/components/Default/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ export function CCComponentEditorRendererNodeDefaultRenderer(
<>
<text
fill={theme.palette.textPrimary}
x={props.geometry.rect.position.x}
y={props.geometry.rect.position.y - 5}
x={0}
y={-5}
textAnchor="start"
fontSize={12}
>
{props.component.name}
</text>
<rect
x={props.geometry.rect.position.x}
y={props.geometry.rect.position.y}
width={props.geometry.rect.size.x}
height={props.geometry.rect.size.y}
x={0}
y={0}
width="100%"
height="100%"
fill={theme.palette.white}
stroke={
props.nodeState.isSelected
Expand Down
Loading
Loading