Skip to content

Commit 446a170

Browse files
committed
Draw wires from end to end instead of from node to node
1 parent 84ffa6b commit 446a170

File tree

14 files changed

+225
-168
lines changed

14 files changed

+225
-168
lines changed

TODO.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,4 @@ Dans les petits plus, mettre en couleur les composants pourrait être intéressa
125125
* Unify click-and-drag also from left buttons instead of click-and-move
126126
* Name field for non-input components, done with component anchoring
127127
* Lock component to some "parent" to move them more intuitively
128+
* Draw wires from edge of component to the other edge when connected

simulator/src/components/ALU.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const ALUDef =
4040
const top = -bottom
4141
const topGroupBits = usesExtendedOpcode ? 5 : 3
4242
// top group is built together
43-
const topGroup = groupHorizontal("n", 0, top, topGroupBits)
43+
const topGroup = groupHorizontal("n", 0, top, topGroupBits, undefined, { leadLength: 20 })
4444
const cin = topGroup.pop()!
4545
// extracted to be mapped correctly when switching between reduced/extended opcodes
4646
const opMode = topGroup.pop()!
@@ -50,13 +50,13 @@ export const ALUDef =
5050
B: groupVertical("w", -outputX, inputCenterY, numBits),
5151
Op: topGroup,
5252
Mode: opMode,
53-
Cin: [cin[0], cin[1], "n", `Cin (${S.Components.ALU.InputCinDesc})`],
53+
Cin: [cin[0], cin[1], "n", `Cin (${S.Components.ALU.InputCinDesc})`, { leadLength: 10 }],
5454
},
5555
outs: {
5656
S: groupVertical("e", outputX, 0, numBits),
57-
V: [0, bottom, "s", "V (oVerflow)"],
58-
Z: [2, bottom, "s", "Z (Zero)"],
59-
Cout: [-2, bottom, "s", `Cout (${S.Components.ALU.OutputCoutDesc})`],
57+
V: [0, bottom, "s", "V (oVerflow)", { leadLength: 20 }],
58+
Z: [2, bottom, "s", "Z (Zero)", { leadLength: 20 }],
59+
Cout: [-2, bottom, "s", `Cout (${S.Components.ALU.OutputCoutDesc})`, { leadLength: 20 }],
6060
},
6161
}
6262
},
@@ -169,24 +169,24 @@ export class ALU extends ParametrizedComponentBase<ALURepr> {
169169

170170
// inputs
171171
for (const input of this.inputs.A) {
172-
drawWireLineToComponent(g, input, left, input.posYInParentTransform)
172+
drawWireLineToComponent(g, input)
173173
}
174174
for (const input of this.inputs.B) {
175-
drawWireLineToComponent(g, input, left, input.posYInParentTransform)
175+
drawWireLineToComponent(g, input)
176176
}
177177
for (const input of this.inputs.Op) {
178-
drawWireLineToComponent(g, input, input.posXInParentTransform, lowerTop)
178+
drawWireLineToComponent(g, input)
179179
}
180-
drawWireLineToComponent(g, this.inputs.Mode, this.inputs.Mode.posXInParentTransform, lowerTop)
181-
drawWireLineToComponent(g, this.inputs.Cin, this.inputs.Cin.posXInParentTransform, lowerTop)
180+
drawWireLineToComponent(g, this.inputs.Mode)
181+
drawWireLineToComponent(g, this.inputs.Cin)
182182

183183
// outputs
184184
for (const output of this.outputs.S) {
185-
drawWireLineToComponent(g, output, right, output.posYInParentTransform)
185+
drawWireLineToComponent(g, output)
186186
}
187-
drawWireLineToComponent(g, this.outputs.Z, this.outputs.Z.posXInParentTransform, bottom - 17)
188-
drawWireLineToComponent(g, this.outputs.V, this.outputs.V.posXInParentTransform, bottom - 9)
189-
drawWireLineToComponent(g, this.outputs.Cout, this.outputs.Cout.posXInParentTransform, bottom - 3)
187+
drawWireLineToComponent(g, this.outputs.Z)
188+
drawWireLineToComponent(g, this.outputs.V)
189+
drawWireLineToComponent(g, this.outputs.Cout)
190190

191191
// outline
192192
g.fillStyle = COLOR_BACKGROUND

simulator/src/components/Component.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as t from "io-ts"
22
import JSON5 from "json5"
33
import type { ComponentKey, DefAndParams, LibraryButtonOptions, LibraryButtonProps, LibraryItem } from "../ComponentMenu"
44
import { DrawParams, LogicEditor } from "../LogicEditor"
5-
import { COLOR_BACKGROUND, COLOR_COMPONENT_INNER_LABELS, COLOR_GROUP_SPAN, DrawingRect, GRID_STEP, drawClockInput, drawComponentName, drawLabel, drawWireLineToComponent, isTrivialNodeName, shouldShowNode, useCompact } from "../drawutils"
5+
import { COLOR_BACKGROUND, COLOR_COMPONENT_INNER_LABELS, COLOR_GROUP_SPAN, DrawingRect, GRID_STEP, drawClockInput, drawComponentName, drawLabel, drawWireLineToComponent, isTrivialNodeName, shouldShowWiresTo, useCompact } from "../drawutils"
66
import { IconName, ImageName } from "../images"
77
import { S, Template } from "../strings"
88
import { ArrayFillUsing, ArrayOrDirect, EdgeTrigger, Expand, FixedArrayMap, HasField, HighImpedance, InteractionResult, LogicValue, LogicValueRepr, Mode, Unknown, brand, deepArrayEquals, isArray, isBoolean, isNumber, isRecord, isString, mergeWhereDefined, toLogicValueRepr, typeOrUndefined, validateJson } from "../utils"
@@ -196,10 +196,19 @@ export const ComponentNameRepr = typeOrUndefined(
196196
])
197197
)
198198

199-
export type NodeOutDesc = readonly [x: number, y: number, orient: Orientation, fullName?: string, opts?: { hasTriangle?: boolean, labelName?: string }]
200-
export type NodeInDesc = readonly [x: number, y: number, orient: Orientation, fullName?: string, opts?: { hasTriangle?: boolean, labelName?: string, prefersSpike?: boolean, isClock?: boolean }]
199+
type NodeOutDescOptions = { hasTriangle?: boolean, labelName?: string, leadLength?: number }
200+
export type NodeOutDesc =
201+
| readonly [x: number, y: number, orient: Orientation, opts?: NodeOutDescOptions]
202+
| readonly [x: number, y: number, orient: Orientation, fullName?: string, opts?: NodeOutDescOptions]
203+
204+
205+
type NodeInDescOptions = { hasTriangle?: boolean, labelName?: string, leadLength?: number, prefersSpike?: boolean, isClock?: boolean }
206+
export type NodeInDesc =
207+
| readonly [x: number, y: number, orient: Orientation, opts?: NodeInDescOptions]
208+
| readonly [x: number, y: number, orient: Orientation, fullName?: string, opts?: NodeInDescOptions]
209+
201210
export type NodeDesc = NodeOutDesc | NodeInDesc
202-
export type NodeDescInGroup = readonly [x: number, y: number, shortNameOverride?: string]
211+
export type NodeDescInGroup = readonly [x: number, y: number, shortNameOverride?: string, opts?: NodeInDescOptions]
203212
export type NodeGroupDesc<D extends NodeDesc> = ReadonlyArray<D>
204213
export type NodeGroupMultiDesc<D extends NodeDesc> = ReadonlyArray<NodeGroupDesc<D>>
205214
export type NodeRec<D extends NodeDesc> = Record<string, D | NodeGroupDesc<D> | NodeGroupMultiDesc<D>>
@@ -417,6 +426,7 @@ export abstract class ComponentBase<
417426
_gridOffsetY: number,
418427
hasTriangle: boolean,
419428
orient: Orientation,
429+
leadLength: number | undefined,
420430
) => TNode) {
421431

422432
const nodes: Record<string, TNode | ReadonlyArray<TNode> | ReadonlyArray<ReadonlyArray<TNode>>> = {}
@@ -426,10 +436,20 @@ export abstract class ComponentBase<
426436
if (nodeRec !== undefined) {
427437
const makeNode = (group: NodeGroup<TNode> | undefined, shortName: string, desc: TDesc) => {
428438
const spec = specs[nextSpecIndex++]
429-
const [offsetX, offsetY, orient, nameOverride, options_] = desc
430-
const options = options_ as NodeInDesc[4] // bleh
439+
const [offsetX, offsetY, orient, nameOrOptions, options_] = desc
440+
let nameOverride: string | undefined = undefined
441+
let options: NodeInDescOptions | undefined = undefined
442+
if (isString(nameOrOptions)) {
443+
nameOverride = nameOrOptions
444+
} else if (nameOrOptions !== undefined) {
445+
options = nameOrOptions
446+
}
447+
if (options_ !== undefined) {
448+
options = options_
449+
}
431450
const isClock = options?.isClock ?? false
432451
const prefersSpike = options?.prefersSpike ?? false
452+
const leadLength = options?.leadLength
433453
const hasTriangle = options?.hasTriangle ?? false
434454
if (group !== undefined && nameOverride !== undefined) {
435455
// names in groups are considered short names to be used as labels
@@ -449,6 +469,7 @@ export abstract class ComponentBase<
449469
offsetY,
450470
hasTriangle,
451471
orient,
472+
leadLength,
452473
)
453474
if (prefersSpike || isClock) {
454475
if (newNode instanceof NodeIn) {
@@ -874,12 +895,11 @@ export abstract class ComponentBase<
874895
return
875896
}
876897

877-
const offset = node.hasTriangle ? 3 : 0
878-
drawWireLineToComponent(g, node, ...this.anchorFor(node, bounds, offset), node.hasTriangle)
898+
drawWireLineToComponent(g, node)
879899
}
880900

881901
protected drawGroupBox(g: GraphicsRendering, group: NodeGroup<Node>, bounds: DrawingRect) {
882-
if (!shouldShowNode(group.nodes)) {
902+
if (!shouldShowWiresTo(group.nodes)) {
883903
return
884904
}
885905

@@ -1459,15 +1479,15 @@ export abstract class ParametrizedComponentBase<
14591479
//
14601480

14611481
export function group<const TDescArr extends readonly NodeDescInGroup[]>(orient: Orientation, nodes: TDescArr) {
1462-
return FixedArrayMap(nodes, ([x, y, name]) => [x, y, orient, name] as const)
1482+
return FixedArrayMap(nodes, ([x, y, name, opts]) => [x, y, orient, name, opts] as const)
14631483
}
14641484

1465-
export function groupVertical(orient: "e" | "w", x: number, yCenter: number, num: number, spacing?: number) {
1485+
export function groupVertical(orient: "e" | "w", x: number, yCenter: number, num: number, spacing?: number, opts?: NodeInDescOptions) {
14661486
const spacing_ = spacing ?? (useCompact(num) ? 1 : 2)
14671487
const span = (num - 1) * spacing_
14681488
const yTop = yCenter - span / 2
14691489
return group(orient,
1470-
ArrayFillUsing(i => [x, yTop + i * spacing_], num)
1490+
ArrayFillUsing(i => [x, yTop + i * spacing_, undefined, opts], num)
14711491
)
14721492
}
14731493

@@ -1482,12 +1502,12 @@ export function groupVerticalMulti(orient: "e" | "w", x: number, yCenter: number
14821502
), numOuter)
14831503
}
14841504

1485-
export function groupHorizontal(orient: "n" | "s", xCenter: number, y: number, num: number, spacing?: number) {
1505+
export function groupHorizontal(orient: "n" | "s", xCenter: number, y: number, num: number, spacing?: number, opts?: NodeInDescOptions) {
14861506
const spacing_ = spacing ?? (useCompact(num) ? 1 : 2)
14871507
const span = (num - 1) * spacing_
14881508
const xRight = xCenter + span / 2
14891509
return group(orient,
1490-
ArrayFillUsing(i => [xRight - i * spacing_, y], num)
1510+
ArrayFillUsing(i => [xRight - i * spacing_, y, undefined, opts], num)
14911511
)
14921512
}
14931513

simulator/src/components/Demux.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export const DemuxDef =
5858
return {
5959
ins: {
6060
In: groupVertical("w", inX, 0, numFrom),
61-
S: groupHorizontal(controlPinsAtBottom ? "s" : "n", 0, selY, numSel),
61+
S: groupHorizontal(controlPinsAtBottom ? "s" : "n", 0, selY, numSel, undefined, { leadLength: 35 }),
6262
},
6363
outs: {
6464
Z: groupOfOutputs,
@@ -148,19 +148,19 @@ export class Demux extends ParametrizedComponentBase<DemuxRepr> {
148148

149149
// inputs
150150
for (const input of this.inputs.In) {
151-
drawWireLineToComponent(g, input, left, input.posYInParentTransform)
151+
drawWireLineToComponent(g, input)
152152
}
153153

154154
// selectors
155155
for (const sel of this.inputs.S) {
156-
drawWireLineToComponent(g, sel, sel.posXInParentTransform, top + dy)
156+
drawWireLineToComponent(g, sel)
157157
}
158158

159159

160160
// outputs
161161
for (const outputGroup of this.outputs.Z) {
162162
for (const output of outputGroup) {
163-
drawWireLineToComponent(g, output, right, output.posYInParentTransform)
163+
drawWireLineToComponent(g, output)
164164
}
165165
}
166166

simulator/src/components/DisplayBar.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export class DisplayBar extends DisplayBarBase<DisplayBarRepr, LogicValue> {
211211
public getWidthAndHeight() {
212212
const w = 10
213213
const h = 2
214-
switch (this._display) {
214+
switch (this._display ?? DisplayBarDef.aults.display) {
215215
case "h":
216216
return [w * GRID_STEP, h * GRID_STEP] as const
217217
case "v":
@@ -251,7 +251,9 @@ export class DisplayBar extends DisplayBarBase<DisplayBarRepr, LogicValue> {
251251

252252
private updateInputOffsetX() {
253253
const width = this.getWidthAndHeight()[0]
254-
this.inputs.I.gridOffsetX = -pxToGrid(width / 2) - 2
254+
const input = this.inputs.I
255+
input.gridOffsetX = -pxToGrid(width / 2) - 1
256+
input.updateLeadLength()
255257
}
256258

257259
protected override makeComponentSpecificContextMenuItems(): MenuItems {

0 commit comments

Comments
 (0)