Skip to content

Commit

Permalink
The schematic editor draws Dots.
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-fritchman committed Nov 10, 2022
1 parent 3180f2b commit 894d364
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 175 deletions.
75 changes: 61 additions & 14 deletions Hdl21SchematicEditor/packages/EditorCore/src/drawing/dot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,61 @@ import { Circle } from "two.js/src/shapes/circle";

// Local Imports
import { Point, point } from "../point";
import { exhaust } from "../errors";
import { EntityInterface, Entity, EntityKind } from "./entity";
import { dotStyle } from "./style";
import { EntityKind } from "./entity";
import { Wire } from "./wire";
import { Instance, SchPort, InstancePort } from "./instance";
import { Instance, SchPort } from "./instance";
import { theEditor } from "../editor";
import { Canvas } from "./canvas";

// # Connection Dot
// Interface for "Dot Parents",
// i.e. schematic entities which have dots as children.
export interface DotParent {
removeDot(dot: Dot): void;
}

// # Connection `Dot`
//
// The `Dot` class just looks like a circle in our drawing.
// But it's got among the most fun behavior.
// Each `Dot` has one or more `Wire`s and zero or one `Instance`s attached to it.
// The `update` methods check if the total number of these things has
// decreased to less than or equal to *one*,
// and if so, the dot is removed.
// In our editor it essentially does "reference counting"
// among things it may be connecting: wires, instances, and ports.
//
// Dots keep a set of references to their parents, and their parents
// keep references to each Dot. When a parent moves or otherwise no longer
// "uses" the Dot, it removes the Dot from its set of children, and calls
// the associated `remove` method on the Dot.
//
// When a Dot detects that it is only "connecting" a single parent, it
// essentially "garbage collects" itself, removing itself, from
// the remaining parent and from the canvas.
// Note it *does not* remove itself from the `Schematic`.
//
export class Dot {
constructor(readonly loc: Point, public drawing: Circle) {}
constructor(readonly loc: Point, private drawing: Circle) {}

entityKind: EntityKind.Dot = EntityKind.Dot;
entityId: number | null = null;

wires: Array<Wire> = [];
instance: Instance | null = null;
// Data structures of parent entities
wires: Set<Wire> = new Set();
instances: Set<Instance> = new Set();
ports: Set<SchPort> = new Set();

highlighted: boolean = false;
canvas: Canvas = theEditor.canvas; // Reference to the drawing canvas. FIXME: the "the" part.

static create(loc: Point): Dot {
return new Dot(loc, this.createDrawing(loc));
}
static createDrawing(loc: Point): Circle {
return new Circle(loc.x, loc.y, 4);
return new Circle(loc.x, loc.y);
}

draw = () => {
this.drawing.remove();
this.drawing = Dot.createDrawing(this.loc);
this.canvas.dotLayer.add(this.drawing);
dotStyle(this.drawing);
if (this.highlighted) {
this.highlight();
}
Expand Down Expand Up @@ -63,5 +84,31 @@ export class Dot {
};
abort = () => {};

updateInstance = (instance: Instance | null) => {};
addInstance = (instance: Instance) => this.instances.add(instance);
removeInstance = (instance: Instance) => this.instances.delete(instance);
addPort = (port: SchPort) => this.ports.add(port);
removePort = (port: SchPort) => this.ports.delete(port);
addWire = (wire: Wire) => this.wires.add(wire);
removeWire = (wire: Wire) => this.wires.delete(wire);

// Check if we are connecting anything, and if not, remove ourselves.
// Generally should be called after removing a parent.
maybeRemove = () => {
if (this.refCount() <= 1) {
this.remove();
}
};
// Remove this dot from its parents and the canvas.
remove = () => {
this.parents().forEach((parent) => parent.removeDot(this));
this.drawing.remove();
};
// Combined array of parent entities
parents = () => {
return [...this.wires, ...this.instances, ...this.ports];
};
// Calculate our "reference count", i.e. the number of things attached to us.
refCount = () => {
return this.wires.size + this.instances.size + this.ports.size;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Rotation, nextRotation } from "../orientation";
import { Canvas } from "./canvas";
import { theEditor } from "../editor";
import { MousePos } from "../mousepos";
import { Dot, DotParent } from "./dot";
import { exhaust } from "../errors";

// FIXME! fill these guys in
Expand Down Expand Up @@ -172,7 +173,7 @@ interface DrawingData {
}

// Base Class shared by `Instance` and `SchPort`
abstract class InstancePortBase implements LabelParent, Placeable {
abstract class InstancePortBase implements LabelParent, DotParent, Placeable {
constructor(
public drawing: Drawing // Drawing data
) {}
Expand All @@ -182,6 +183,7 @@ abstract class InstancePortBase implements LabelParent, Placeable {
entityId: number | null = null; // Numeric unique ID
bbox: Bbox = bbox.empty(); // Bounding Box
highlighted: boolean = false;
dots: Set<Dot> = new Set();

abstract createLabels(): void; // Create all Labels
abstract drawingData(): DrawingData; // Get data for drawing
Expand Down Expand Up @@ -272,6 +274,10 @@ abstract class InstancePortBase implements LabelParent, Placeable {
}
this.draw();
};

removeDot(dot: Dot): void {
this.dots.delete(dot);
}
}

// # Schematic Instance
Expand Down
Loading

0 comments on commit 894d364

Please sign in to comment.