Skip to content

Commit

Permalink
feat: schDisplayLabel prop for <trace /> with test. (tscircuit#381)
Browse files Browse the repository at this point in the history
* feat: schDisplayLabel prop for <trace /> with tests

* improved the logic to handel path prop and errors

* improved the PR
  • Loading branch information
Abse2001 authored Dec 4, 2024
1 parent d5aa673 commit 8674cb8
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 3 deletions.
Binary file modified bun.lockb
Binary file not shown.
108 changes: 106 additions & 2 deletions lib/components/primitive-components/Trace/Trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@ import { getStubEdges } from "lib/utils/schematic/getStubEdges"
import { tryNow } from "lib/utils/try-now"
import { z } from "zod"
import { PrimitiveComponent } from "../../base-components/PrimitiveComponent"
import type { Net } from "../Net"
import { Net } from "../Net"
import type { Port } from "../Port"
import type { TraceHint } from "../TraceHint"
import type { TraceI } from "./TraceI"
import { createSchematicTraceCrossingSegments } from "./create-schematic-trace-crossing-segments"
import { createSchematicTraceJunctions } from "./create-schematic-trace-junctions"
import { pushEdgesOfSchematicTraceToPreventOverlap } from "./push-edges-of-schematic-trace-to-prevent-overlap"

type PcbRouteObjective =
| RouteHintPoint
| {
Expand Down Expand Up @@ -595,6 +594,99 @@ export class Trace
}
}
}
_doInitialSchematicTraceRenderWithDisplayLabel(): void {
if (this.root?.schematicDisabled) return
const { db } = this.root!
const { _parsedProps: props, parent } = this

if (!parent) throw new Error("Trace has no parent")

const { allPortsFound, portsWithSelectors: connectedPorts } =
this._findConnectedPorts()

if (!allPortsFound) return

const portsWithPosition = connectedPorts.map(({ port }) => ({
port,
position: port._getGlobalSchematicPositionAfterLayout(),
schematic_port_id: port.schematic_port_id ?? undefined,
facingDirection: port.facingDirection,
}))
if (portsWithPosition.length < 2) {
throw new Error("Expected at least two ports in portsWithPosition.")
}

let fromPortName: any
let toPortName: any
const fromAnchorPos = portsWithPosition[0].position
const fromPort = portsWithPosition[0].port

// Validate `path`, `from`, and `to`
if ("path" in this.props) {
if (this.props.path.length !== 2) {
throw new Error("Invalid 'path': Must contain exactly two elements.")
}
;[fromPortName, toPortName] = this.props.path
} else {
if (!("from" in this.props && "to" in this.props)) {
throw new Error("Missing 'from' or 'to' properties in props.")
}
fromPortName = this.props.from
toPortName = this.props.to
}

if (!fromPort.source_port_id) {
throw new Error(
`Missing source_port_id for the 'from' port (${fromPortName}).`,
)
}
const toAnchorPos = portsWithPosition[1].position
const toPort = portsWithPosition[1].port

if (!toPort.source_port_id) {
throw new Error(
`Missing source_port_id for the 'to' port (${toPortName}).`,
)
}

// Handle `from` port label
const existingFromNetLabel = db.schematic_net_label
.list()
.find((label) => label.source_net_id === fromPort.source_port_id)

const existingToNetLabel = db.schematic_net_label
.list()
.find((label) => label.source_net_id === toPort.source_port_id)

if (
(existingFromNetLabel &&
existingFromNetLabel.text !== this.props.schDisplayLabel) ||
(existingToNetLabel &&
existingToNetLabel?.text !== this.props.schDisplayLabel)
) {
throw new Error(
`Cannot create net label for port ${existingFromNetLabel ? fromPortName : toPortName} because it already has a net label with text "${existingFromNetLabel ? existingFromNetLabel.text : existingToNetLabel?.text}".`,
)
}
db.schematic_net_label.insert({
text: this.props.schDisplayLabel!,
source_net_id: fromPort.source_port_id!,
anchor_position: fromAnchorPos,
center: fromAnchorPos,
anchor_side:
getEnteringEdgeFromDirection(fromPort.facingDirection!) ?? "bottom",
})
// Handle `to` port label

db.schematic_net_label.insert({
text: this.props.schDisplayLabel!,
source_net_id: toPort.source_port_id!,
anchor_position: toAnchorPos,
center: toAnchorPos,
anchor_side:
getEnteringEdgeFromDirection(toPort.facingDirection!) ?? "bottom",
})
}

doInitialSchematicTraceRender(): void {
if (this.root?.schematicDisabled) return
Expand All @@ -614,6 +706,13 @@ export class Trace
name: this.source_trace_id!,
pointsToConnect: [],
}
if (
this.props.schDisplayLabel &&
(("from" in this.props && "to" in this.props) || "path" in this.props)
) {
this._doInitialSchematicTraceRenderWithDisplayLabel()
return
}

// Add obstacles from components and ports
for (const elm of db.toArray()) {
Expand Down Expand Up @@ -781,6 +880,11 @@ export class Trace
}),
)

// Handle case where no labels are created and trace is inserted
if (!this.source_trace_id) {
throw new Error("Missing source_trace_id for schematic trace insertion.")
}

const trace = db.schematic_trace.insert({
source_trace_id: this.source_trace_id!,
edges,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"@tscircuit/footprinter": "^0.0.89",
"@tscircuit/infgrid-ijump-astar": "^0.0.24",
"@tscircuit/math-utils": "^0.0.5",
"@tscircuit/props": "^0.0.107",
"@tscircuit/props": "^0.0.108",
"@tscircuit/schematic-autolayout": "^0.0.6",
"@tscircuit/soup-util": "^0.0.41",
"circuit-json": "^0.0.108",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions tests/examples/example10-schDisplayLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { expect, test } from "bun:test"
import { getTestFixture } from "../fixtures/get-test-fixture"

test("Should not render any schematic components", async () => {
const { circuit } = getTestFixture()

circuit.add(
<board width={20} height={20}>
<resistor
name="R1"
footprint="0603"
schX={8}
schY={-1}
pcbX={0}
resistance="10k"
/>
<resistor
name="R2"
footprint="0603"
schX={0}
schY={-1}
pcbX={4}
resistance="10k"
/>
<capacitor
name="C1"
footprint="0603"
schX={4}
schY={1}
pcbX={-4}
capacitance="10k"
/>
<capacitor
name="C2"
footprint="0603"
schX={2}
schY={0}
pcbX={-8}
capacitance="10k"
/>

<trace from={".C1 > .pin1"} to={".R2 > .pin1"} />
<trace schDisplayLabel="C2_POS" path={[".C1 > .pin2", ".C2 > .pin2"]} />
<trace
pcbRouteHints={[{ x: 2, y: -8 }]}
schDisplayLabel="C2_POS"
from={".C2 > .pin2"}
to={".R1 > .pin2"}
/>
<trace
pcbRouteHints={[{ x: 2, y: -8 }]}
schDisplayLabel="R1_1"
from={".R1 > .pin1"}
to={".C2 > .pin1"}
/>
</board>,
)

circuit.render()
expect(circuit).toMatchPcbSnapshot(import.meta.path)
expect(circuit).toMatchSchematicSnapshot(import.meta.path)
})

0 comments on commit 8674cb8

Please sign in to comment.