Skip to content

Commit

Permalink
Get rendering/exe working with sub schematics
Browse files Browse the repository at this point in the history
  • Loading branch information
bbycroft committed Oct 31, 2023
1 parent 235f1b6 commit fcf7b8a
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 39 deletions.
12 changes: 7 additions & 5 deletions src/cpu/CanvasEventHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -487,20 +487,22 @@ export const CanvasEventHandler: React.FC<{
let bb = new BoundingBox3d(comp.pos, comp.pos.add(comp.size));
if (bb.contains(mousePt)) {

if (comp.hasSubSchematic && editorState.maskHover !== comp.id) {
if ((comp.hasSubSchematic || comp.subSchematicId) && editorState.maskHover !== comp.id) {
let screenBb = mtx.mulBb(bb).shrinkInPlaceXY(20);
if (screenBb.contains(mousePtScreen)) {
// need some test of whether we can click through to the sub-schematic,
// since still want to be able to select the component itself. Also should
// be related to zoom level
let def = editorState.compLibrary.getCompDef(comp.defId);
let subMtx = mtx.mul(computeSubLayoutMatrix(comp, def!, def!.subLayout!.layout));
let subSchematic = getCompSubSchematic(editorState, comp)!;
if (subSchematic && def) {
let subMtx = mtx.mul(computeSubLayoutMatrix(comp, def!, subSchematic));

let subRef = getRefUnderCursor(editorState, ev, subSchematic, subMtx, idPrefix + comp.id + '|');
let subRef = getRefUnderCursor(editorState, ev, subSchematic, subMtx, idPrefix + comp.id + '|');

if (subRef) {
refsUnderCursor.push(subRef);
if (subRef) {
refsUnderCursor.push(subRef);
}
}
continue;
}
Expand Down
15 changes: 7 additions & 8 deletions src/cpu/CpuCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export const CpuCanvas: React.FC<{
let ctx = sharedContext ?? createSharedContext();
setEditorState(a => {
return assignImm(a, {
sharedContext: ctx,
codeLibrary: ctx.codeLibrary,
schematicLibrary: ctx.schematicLibrary,
compLibrary: ctx.compLibrary,
Expand Down Expand Up @@ -143,14 +144,14 @@ export const CpuCanvas: React.FC<{
let prev = prevExeModel.current;
let sameId = prev && prev.id === editorState.activeSchematicId;

let model = createExecutionModel(editorState.compLibrary, editorState.snapshot, prev && sameId ? prev.system : null);
let model = createExecutionModel(editorState.sharedContext, editorState.snapshot, prev && sameId ? prev.system : null);

if (isClient) {
stepExecutionCombinatorial(model);
}

return model;
}, [editorState.activeSchematicId, editorState.snapshot, editorState.compLibrary, isClient]);
}, [editorState.sharedContext, editorState.snapshot, editorState.activeSchematicId, isClient]);

prevExeModel.current = { system: exeModel, id: editorState.activeSchematicId };

Expand Down Expand Up @@ -219,11 +220,10 @@ export const CpuCanvas: React.FC<{
let comps = schematic.comps
.map(comp => {
let def = editorState.compLibrary.getCompDef(comp.defId)!;
return (def.renderDom || def.subLayout) && cvsState ? {
return (def.renderDom || def.subLayout || comp.subSchematicId) && cvsState ? {
comp,
def,
renderDom: def.renderDom,
subLayout: def.subLayout,
} : null;
})
.filter(isNotNil)
Expand All @@ -233,15 +233,14 @@ export const CpuCanvas: React.FC<{

let subLayoutDom = null;
let subSchematic = getCompSubSchematic(editorState, a.comp);
if (a.subLayout || subSchematic) {
let schematic = a.subLayout?.layout ?? subSchematic!;
let subMtx = computeSubLayoutMatrix(a.comp, a.def, schematic);
if (subSchematic) {
let subMtx = computeSubLayoutMatrix(a.comp, a.def, subSchematic);

subLayoutDom = <div
className={"absolute origin-top-left"}
style={{ transform: `matrix(${subMtx.toTransformParams().join(',')})` }}
>
{getCompDomElements(schematic, idPrefix + a.comp.id + '|')}
{getCompDomElements(subSchematic, idPrefix + a.comp.id + '|')}
</div>;
}

Expand Down
25 changes: 14 additions & 11 deletions src/cpu/CpuExecution.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { getOrAddToMap, hasFlag, isNotNil } from "../utils/data";
import { CompLibrary, IResetOptions } from "./comps/CompBuilder";
import { compPortDefId, ICompPortConfig, ICompPortData } from "./comps/CompPort";
import { PortType, IEditSnapshot, IExeComp, IExeNet, IExePortRef, IExeSystem, RefType, IExeStep, IExeSystemLookup, IElRef, IoDir, IExePort, ISchematic, IComp } from "./CpuModel";
import { PortType, IEditSnapshot, IExeComp, IExeNet, IExePortRef, IExeSystem, RefType, IExeStep, IExeSystemLookup, IElRef, IoDir, IExePort, ISchematic, IComp, IEditorState } from "./CpuModel";
import { ISharedContext } from "./library/SharedContext";
import { getCompSubSchematic, getCompSubSchematicForSnapshot } from "./SubSchematics";

/*
Expand Down Expand Up @@ -30,10 +32,10 @@ Having real trouble passing data between external & internal ports.
*/

export function createExecutionModel(compLibrary: CompLibrary, displayModel: IEditSnapshot, existingSystem: IExeSystem | null): IExeSystem {
export function createExecutionModel(sharedContext: ISharedContext, displayModel: IEditSnapshot, existingSystem: IExeSystem | null): IExeSystem {

let exeSystem: IExeSystem = {
compLibrary,
compLibrary: sharedContext.compLibrary,
comps: [],
nets: [],
executionSteps: [],
Expand All @@ -42,7 +44,7 @@ export function createExecutionModel(compLibrary: CompLibrary, displayModel: IEd
runArgs: { halt: false },
};

populateExecutionModel(exeSystem, displayModel, '', existingSystem);
populateExecutionModel(sharedContext, displayModel, exeSystem, displayModel, '', existingSystem);

let executionOrder = calcCompExecutionOrder(exeSystem.comps, exeSystem.nets);

Expand All @@ -55,8 +57,8 @@ export function createExecutionModel(compLibrary: CompLibrary, displayModel: IEd
return exeSystem;
}

export function populateExecutionModel(exeSystem: IExeSystem, schematic: ISchematic, subTreePrefix: string, existingSystem: IExeSystem | null) {
let compLibrary = exeSystem.compLibrary;
export function populateExecutionModel(sharedContext: ISharedContext, editSnapshot: IEditSnapshot, exeSystem: IExeSystem, schematic: ISchematic, subTreePrefix: string, existingSystem: IExeSystem | null) {
let compLibrary = sharedContext.compLibrary;
// we build the subtree prefix as "id|subId|"
let connectedWires = schematic.wires;
let connectedComps = schematic.comps;
Expand All @@ -71,9 +73,10 @@ export function populateExecutionModel(exeSystem: IExeSystem, schematic: ISchema

for (let comp of schematic.comps) {
let def = compLibrary.getCompDef(comp.defId)!;
if (def.subLayout) {
let subSchematic = getCompSubSchematicForSnapshot(sharedContext, editSnapshot, comp);
if (subSchematic) {
let prefix = subTreePrefix + comp.id + '|';
populateExecutionModel(exeSystem, def.subLayout.layout, prefix, existingSystem);
populateExecutionModel(sharedContext, editSnapshot, exeSystem, subSchematic, prefix, existingSystem);
}

let fullCompId = subTreePrefix + comp.id;
Expand All @@ -96,10 +99,10 @@ export function populateExecutionModel(exeSystem: IExeSystem, schematic: ISchema
exeSystem.lookup.compIdToIdx.set(fullCompId, newCompIdx);
exeSystem.comps.push(exeComp);

if (def.subLayout) {
if (subSchematic) {
let prefix = subTreePrefix + comp.id + '|';

let innerSchematicPorts = def.subLayout.layout.comps.filter(a => a.defId === compPortDefId) as IComp<ICompPortConfig>[];
let innerSchematicPorts = subSchematic.comps.filter(a => a.defId === compPortDefId) as IComp<ICompPortConfig>[];

let nestedComps = exeComp.ports.map(exePort => {
let port = exeComp.comp.ports[exePort.portIdx];
Expand Down Expand Up @@ -298,7 +301,7 @@ export function calcCompExecutionOrder(comps: IExeComp[], nets: IExeNet[]): { ex
let port = comp.ports[portIdx];
let net = nets[port.netIdx];
if (!net) {
console.log('comp', comp, 'port', port, 'has no net');
// console.log('comp', comp, 'port', port, 'has no net');
continue;
}
let netPhaseCount = netNumPhases.get(port.netIdx)!;
Expand Down
5 changes: 5 additions & 0 deletions src/cpu/CpuModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AffineMat2d } from "../utils/AffineMat2d";
import { BoundingBox3d, Vec3 } from "../utils/vector";
import { CompLibrary, ICompDef } from "./comps/CompBuilder";
import { CodeSuiteManager } from "./library/CodeSuiteManager";
import { ISharedContext } from "./library/SharedContext";
import { SchematicLibrary } from "./schematics/SchematicLibrary";

/* All components & schematics and each version of them is represented by a separate ILibraryItem.
Expand Down Expand Up @@ -131,6 +132,7 @@ export interface IEditorState {
activeSchematicId: string | null;

// time to combine these!! Actually, let's use CompLibrary, since it's used in more places, & rename it
sharedContext: ISharedContext;
compLibrary: CompLibrary;
schematicLibrary: SchematicLibrary;
codeLibrary: CodeSuiteManager;
Expand Down Expand Up @@ -303,6 +305,9 @@ export interface IEditSnapshot {
compPorts: ICompPort[];
compBbox: BoundingBox3d;

// what's the key here?
// for builtins with "subSchematicId", want the key to be the same
// for custom components, also want this?
subComps: Map<string, IEditSchematic>;
}

Expand Down
22 changes: 14 additions & 8 deletions src/cpu/HoverDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import { hasFlag } from "../utils/data";
import { hasFlag, isNotNil } from "../utils/data";
import { Popup, PopupPos } from "../utils/Portal";
import { Vec3 } from "../utils/vector";
import { ensureSigned32Bit, ensureUnsigned32Bit, signExtend32Bit } from "./comps/RiscvInsDecode";
import { lookupPortInfo, netToString } from "./CpuExecution";
import { ISchematic, IoDir, PortType, RefType } from "./CpuModel";
import { useEditorContext } from "./Editor";
import s from "./HoverDisplay.module.scss";
import { computeSubLayoutMatrix } from "./SubSchematics";
import { computeSubLayoutMatrix, getCompSubSchematic } from "./SubSchematics";

export const HoverDisplay: React.FC<{
canvasEl: HTMLCanvasElement | null,
Expand Down Expand Up @@ -63,7 +63,8 @@ export const HoverDisplay: React.FC<{

} else {
let compIdx = exeModel.lookup.compIdToIdx.get(hovered.ref.id);
let comp = exeModel.comps[compIdx ?? -1];
let idxFound = isNotNil(compIdx);
let exeComp = exeModel.comps[compIdx ?? -1];

let portElNode: React.ReactNode = null;
let portIdStr: React.ReactNode = null;
Expand Down Expand Up @@ -105,14 +106,14 @@ export const HoverDisplay: React.FC<{
}
}

if (comp) {
if (exeComp) {
content = <div>
<div>{portElNode ?? comp.comp.name}</div>
<div className={s.compId}>{comp.comp.id}/{comp.comp.defId}{portIdStr}</div>
<div>{portElNode ?? exeComp.comp.name}</div>
<div className={s.compId}>{exeComp.comp.id}/{exeComp.comp.defId}{portIdStr}</div>
</div>;

} else {
content = <div>comp {hovered.ref.id} not found</div>;
content = <div>comp {hovered.ref.id} not found {idxFound ? `but has idx ${idxFound}` : 'and exeComp idx not found'}</div>;
}
}

Expand All @@ -126,8 +127,13 @@ export const HoverDisplay: React.FC<{
if (!comp || !def) {
break;
}
let subMtx = computeSubLayoutMatrix(comp, def, def.subLayout!.layout);
let subSchematic = getCompSubSchematic(editorState, comp);
if (!subSchematic) {
break;
}
let subMtx = computeSubLayoutMatrix(comp, def, subSchematic);
mtx = mtx.mul(subMtx);
schematic = subSchematic;
}

let offset = new Vec3(20, 20);
Expand Down
3 changes: 3 additions & 0 deletions src/cpu/ImportExport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export interface ILSComp {
x: number;
y: number;
args?: any;
subSchematicId?: string;
}

export interface ILSGraphWireNode {
Expand Down Expand Up @@ -343,6 +344,7 @@ export function wiresFromLsState(layoutBase: IEditSnapshot, ls: ILSState, compLi

comp.id = c.id;
comp.pos = new Vec3(c.x, c.y);
comp.subSchematicId = c.subSchematicId;

return comp;
});
Expand Down Expand Up @@ -373,6 +375,7 @@ export function schematicToLsState(layout: ISchematic): ILSState {
x: c.pos.x,
y: c.pos.y,
args: c.args,
subSchematicId: c.subSchematicId,
})),
};
}
Expand Down
1 change: 1 addition & 0 deletions src/cpu/ModelHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function createCpuEditorState(sharedContext: ISharedContext | null): IEdi
snapshot: editSnapshot, // wiresFromLsState(constructEditSnapshot(), lsState, compLibrary),
snapshotTemp: null,
mtx: AffineMat2d.multiply(AffineMat2d.scale1(10), AffineMat2d.translateVec(new Vec3(1920/2, 1080/2).round())),
sharedContext,
compLibrary: sharedContext.compLibrary,
schematicLibrary: sharedContext.schematicLibrary,
codeLibrary: sharedContext.codeLibrary,
Expand Down
24 changes: 17 additions & 7 deletions src/cpu/SubSchematics.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { subscribe } from "diagnostics_channel";
import { AffineMat2d } from "../utils/AffineMat2d";
import { BoundingBox3d, Vec3 } from "../utils/vector";
import { IComp, IEditorState, ISchematic } from "./CpuModel";
import { IComp, IEditSnapshot, IEditorState, ISchematic } from "./CpuModel";
import { ICompDef } from "./comps/CompBuilder";
import { ISharedContext } from "./library/SharedContext";

export function computeSubLayoutMatrix(comp: IComp, compDef: ICompDef<any>, subSchematic: ISchematic) {
if (!subSchematic.comps) {
Expand Down Expand Up @@ -42,16 +42,26 @@ export function getCompSubSchematic(editorState: IEditorState, comp: IComp): ISc

let snapshot = editorState.snapshotTemp ?? editorState.snapshot;

let subComp = snapshot.subComps.get(comp.id);
if (subComp) {
return subComp;
return getCompSubSchematicForSnapshot(editorState.sharedContext, snapshot, comp);
}

export function getCompSubSchematicForSnapshot(sharedContext: ISharedContext, snapshot: IEditSnapshot, comp: IComp): ISchematic | null {
if (!comp.hasSubSchematic && !comp.subSchematicId) {
return null;
}

if (comp.subSchematicId) {
return editorState.schematicLibrary.getSchematic(comp.subSchematicId)?.model ?? null;
let editSchematic = snapshot.subComps.get(comp.subSchematicId);
if (editSchematic) {
return editSchematic;
}

let schemLibEntry = sharedContext.schematicLibrary.getSchematic(comp.subSchematicId);

return schemLibEntry?.model ?? null;
}

let compDef = editorState.compLibrary.getCompDef(comp.defId);
let compDef = sharedContext.compLibrary.getCompDef(comp.defId);
return compDef?.subLayout?.layout ?? null;
}

Expand Down

0 comments on commit fcf7b8a

Please sign in to comment.