Skip to content

Commit

Permalink
fix port matching, introduce primitive containers
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Sep 5, 2024
1 parent 965c25a commit c7f85c0
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 11 deletions.
2 changes: 2 additions & 0 deletions lib/components/base-components/NormalComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export class NormalComponent<
> extends PrimitiveComponent<ZodProps> {
reactSubtrees: Array<ReactSubtree> = []

isPrimitiveContainer = true

constructor(props: z.input<ZodProps>) {
super(props)
this._addChildrenFromStringFootprint()
Expand Down
17 changes: 17 additions & 0 deletions lib/components/base-components/PrimitiveComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ export abstract class PrimitiveComponent<
)
}

/**
* A primitive container is a component that contains one or more ports and
* primitive components that are designed to interact.
*
* For example a resistor contains ports and smtpads that interact, so the
* resistor is a primitive container. Inside a primitive container, the ports
* and pads are likely to reference each other and look for eachother during
* the port matching phase.
*
*/
isPrimitiveContainer = false

source_group_id: string | null = null
source_component_id: string | null = null
schematic_component_id: string | null = null
Expand Down Expand Up @@ -148,6 +160,11 @@ export abstract class PrimitiveComponent<
)
}

getPrimitiveContainer(): PrimitiveComponent | null {
if (this.isPrimitiveContainer) return this
return this.parent?.getPrimitiveContainer?.() ?? null
}

/**
* Compute the bounds of this component the circuit json elements associated
* with it.
Expand Down
4 changes: 2 additions & 2 deletions lib/components/base-components/Renderable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import type { PCBPlacementError, PCBTraceError } from "@tscircuit/soup"
import { Component, createElement, type ReactElement } from "react"

export const orderedRenderPhases = [
"ReactSubtreesRender", // probably going to be removed b/c subtrees should render instantly
"ReactSubtreesRender",
"InitializePortsFromChildren",
"CreateNetsFromProps",
"CreateTracesFromProps",
"SourceRender",
"SourceParentAttachment",
"PortDiscovery", // probably going to be removed b/c port discovery can always be done on prop change
"PortDiscovery",
"PortMatching",
"SourceTraceRender",
"SchematicComponentRender",
Expand Down
9 changes: 2 additions & 7 deletions lib/components/primitive-components/Port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,6 @@ export class Port extends PrimitiveComponent<typeof portProps> {
this.source_component_id = this.parent?.source_component_id
}

/**
* For PcbPorts, we use the parent attachment phase to determine where to place
* the pcb_port (prior to this phase, the smtpad/platedhole isn't guaranteed
* to exist)
*/
doInitialPcbPortRender(): void {
const { db } = this.root!
const { matchedComponents } = this
Expand All @@ -173,12 +168,12 @@ export class Port extends PrimitiveComponent<typeof portProps> {

const pcbMatch: any = pcbMatches[0]

if ("_getGlobalPcbPositionBeforeLayout" in pcbMatch) {
if ("_getCircuitJsonBounds" in pcbMatch) {
const pcb_port = db.pcb_port.insert({
pcb_component_id: this.parent?.pcb_component_id!,
layers: ["top"],

...pcbMatch._getGlobalPcbPositionBeforeLayout(),
...pcbMatch._getCircuitJsonBounds().center,

source_port_id: this.source_port_id!,
})
Expand Down
4 changes: 2 additions & 2 deletions lib/components/primitive-components/SmtPad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export class SmtPad extends PrimitiveComponent<typeof smtPadProps> {
}

doInitialPortMatching(): void {
const parentPorts = (this.parent?.children ?? []).filter(
(c) => c.componentName === "Port",
const parentPorts = this.getPrimitiveContainer()?.selectAll(
"port",
) as Port[]

if (!this.props.portHints) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,12 @@ test("footprint layout", () => {
// Should be centered about 0
expect(Math.abs(smtpads[0].x + smtpads[1].x) / 2).toBeCloseTo(0, 1)

const pcbPorts = circuit.db.pcb_port.list()

expect(pcbPorts.length).toBe(2)

expect(pcbPorts[0].x).toBeOneOf([-2, 2])
expect(pcbPorts[1].x).toBeOneOf([-2, 2])

expect(circuit.getCircuitJson()).toMatchPcbSnapshot(import.meta.path)
})

0 comments on commit c7f85c0

Please sign in to comment.