TestProcedureViewer:
PUBLIC
PROC [cellType: Core.CellType, testButtons:
LIST
OF
ROPE, name:
ROPE ←
NIL, displayWires: CoreFlat.FlatWires ←
NIL, graphWires: CoreFlat.FlatWires ←
NIL, cutSet: CoreFlat.CutSet ←
NIL, historySize:
NAT ← 0, steady:
BOOL ←
FALSE, recordDeltas:
BOOL ←
TRUE]
RETURNS [tester: Tester] = {
The RoseDisplay is put as a CellType property and a tester viewer property to ease up data structure destrcution when the viewer is destroyed.
AddButton:
PROC [name:
ROPE, proc: Buttons.ButtonProc, guarded:
BOOL ←
FALSE] ~ {
button: ViewerClasses.Viewer ← Buttons.Create[
info: [name: name, wx: xPos, wy: height, parent: viewer, border: TRUE],
guarded: guarded,
proc: proc, clientData: tester];
xPos ← xPos+button.ww+entryHSpace;
};
AddPrompt:
PROC [title:
ROPE, width:
CARDINAL]
RETURNS [v: ViewerClasses.Viewer] ~ {
v ← ChoiceButtons.BuildTextPrompt[
viewer: viewer,
x: xPos, y: height,
x: xPos, y: height-borderOffset,
title: title, textViewerWidth: width].textViewer;
xPos ← v.wx+v.ww+entryHSpace;
};
viewer: ViewerClasses.Viewer; -- created after simulation has been expanded
height: CARDINAL ← entryVSpace;
xPos: CARDINAL ← entryHSpace;
tester ← NEW[TesterRec];
tester.display ← NEW[RoseDisplayRec];
tester.steadyInit ← steady;
tester.display.cutSet ← cutSet;
tester.intermediatePort ← Ports.CreatePort[cellType, TRUE];
tester.display.cellType ← cellType;
tester.display.recordDeltas ← recordDeltas;
tester.display.simulation ← Rosemary.Instantiate[cellType, tester.intermediatePort, cutSet, historySize];
IF historySize>0
THEN {
tester.historySize ← historySize;
tester.testVectorBuffer ← NEW[Rosemary.PortSequenceRec[historySize]];
FOR b:
NAT
IN [0..historySize)
DO
tester.testVectorBuffer[b] ← Ports.CreatePort[cellType, TRUE];
ENDLOOP;
};
viewer ← Containers.Create[[name: name, iconic: TRUE, column: right, scrollable: FALSE]];
CoreProperties.PutCellTypeProp[cellType, rosemaryHandle, tester.display]; -- for retrieval
ViewerOps.AddProp[viewer, testerProp, tester]; -- for retrieval
[] ← ViewerEvents.RegisterEventProc[proc: TesterDestroyed, event: destroy, filter: viewer, before: TRUE]; -- call proc just before tester viewer is destroyed
AddButton["Start Test", ButtonStartTest];
tester.runState ← AddPrompt[" Run State:", 3*pointsPerInch/2];
ViewerTools.InhibitUserEdits[tester.runState];
ViewerTools.SetContents[tester.runState, "Idle"];
tester.evalsSinceStart ← AddPrompt["Evals Since Start:", 1*pointsPerInch];
ViewerTools.InhibitUserEdits[tester.evalsSinceStart];
height ← height + entryHeight + entryVSpace; xPos ← entryHSpace; -- new line
AddButton["Abort", Abort, TRUE];
AddButton["Interrupt", Interrupt];
AddButton["Single Eval", SingleEval];
AddButton["Proceed", Proceed];
tester.proceedUntil ← AddPrompt["Until:", 1*pointsPerInch];
height ← height + entryHeight + entryVSpace; xPos ← entryHSpace; -- new line
IF historySize>0
THEN {
AddButton["Next State", NextState];
AddButton["Previous State", PreviousState];
tester.historyTrigger ← AddPrompt["History Trigger:", 2*pointsPerInch];
height ← height + entryHeight + entryVSpace; xPos ← entryHSpace; -- new line
};
IF testButtons.rest#
NIL
THEN {
-- more than 1 test proc, show them all for user choice
Column: TYPE = NAT [0..3);
ColumnStart: ARRAY Column OF NAT = [entryVSpace, 2*pointsPerInch+entryVSpace, 4*pointsPerInch+entryVSpace];
column: Column ← 0;
first: Buttons.Button ← NIL;
FOR tbs:
LIST
OF
ROPE ← testButtons, tbs.rest
UNTIL tbs=
NIL
DO
this: Buttons.Button ← Buttons.Create[info: [name: tbs.first,
wx: ColumnStart[column], wy: height,
ww: 0, wh: entryHeight,
parent: viewer, border: TRUE], clientData: tester, proc: TestButtonProc];
tester.testButtonList ← CONS[this, tester.testButtonList];
IF first=NIL THEN first ← this;
IF column=
LAST[Column]
THEN {
column ← 0;
height ← height + entryHeight + entryVSpace;
}
ELSE column ← column+1;
ENDLOOP;
IF column>0 THEN height ← height + entryHeight + entryVSpace;
Buttons.SetDisplayStyle[first, $WhiteOnBlack];
};
tester.currentTestProc ← testButtons.first;
MakeDisplayAndBrowse[displayWires, graphWires, height, tester.display, viewer, name];
};
TesterCleanup:
PROC [tester: Tester, initial: ViewerClasses.Viewer] ~ {
Remove extraneous viewers, destroy backing file, remove circular references if any
display: RoseDisplay ← tester.display;
displayOnCellType: RoseDisplay ← NARROW[CoreProperties.GetCellTypeProp[display.cellType, rosemaryHandle]];
SetUntil[h: tester, count: LAST[INT], trigger: LAST[INT], interrupt: FALSE, abort: TRUE]; -- try to abort simulation, may fail. Should not refer to viewer here as it may be dead!
IF displayOnCellType=display THEN CoreProperties.PutCellTypeProp[display.cellType, rosemaryHandle, NIL]; -- NIL circular ref
IF display.plot#NIL AND display.plot.private#NIL THEN PlotGraph.DeletePlot[display.plot];
ViewerOps.DestroyViewer[ViewerIO.GetViewerFromStream[display.tsout]];
IF display.ps#NIL THEN {IO.SetLength[display.ps, 0]; IO.Close[display.ps]}; -- backing file
};