FILE: RoseDisplayOps.Mesa
Last Edited by: Spreitzer, May 17, 1985 4:05:24 pm PDT
Last Edited by: Barth, June 9, 1983 11:19 am
Last Edited by: Gasbarro, July 17, 1984 3:57:59 pm PDT
DIRECTORY AMBridge, AMTypes, Asserting, Atom, Buttons, HierarchicalDisplays, Icons, IO, Labels, MessageWindow, OrderedSymbolTableRef, PrincOps, PrincOpsUtils, Process, Rope, RoseConditions, RoseCreate, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerClasses, ViewerIO, ViewerOps, ViewerTools, ViewRec;
RoseDisplayOps: CEDAR MONITOR
IMPORTS AMBridge, AMTypes, Asserting, Atom, Buttons, HierarchicalDisplays, Icons, IO, MessageWindow, OrderedSymbolTableRef, PrincOpsUtils, Process, Rope, RoseConditions, RoseCreate, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerIO, ViewerOps, ViewerTools, ViewRec
EXPORTS RoseDisplayInsides =
BEGIN OPEN RoseDisplayInsides;
IncrementalCondition: TYPE = RoseConditions.IncrementalCondition;
NamedCondition: TYPE = REF NamedConditionRep;
NamedConditionRep: TYPE = RECORD [
name: ROPE,
cond: Condition,
ic: IncrementalCondition ← NIL,
posted, postedIncrementally: BOOLEANFALSE
];
displayIcon: Icons.IconFlavor ← Icons.NewIconFromFile["Rosemary.icons", 0];
leafProp: PUBLIC ATOM ← Atom.MakeAtom["January 6, 1984 9:19 pm Spreitzer"];
treeHandler: ViewRec.SimpleHandler ← NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseTree,
Max: MaxTree]];
treeNodeListHandler: ViewRec.SimpleHandler ← NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseTreeNodeList,
Max: MaxTreeNodeList]];
stHandler: ViewRec.SimpleHandler ← NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseST,
Max: MaxST]];
nodeAsNode: REF Node ← NEW [Node ← NIL];
nodeAsTV: AMTypes.TypedVariable ← TVfR[nodeAsNode];
treeAsTree: REF TreeNode ← NEW [TreeNode ← NIL];
treeAsTV: AMTypes.TypedVariable ← TVfR[treeAsTree];
tnlAsTNL: REF TreeNodeList ← NEW [TreeNodeList ← NIL];
tnlAsTV: AMTypes.TypedVariable ← TVfR[tnlAsTNL];
stAsST: REF SymbolTable ← NEW [SymbolTable ← NIL];
stAsTV: AMTypes.TypedVariable ← TVfR[stAsST];
TVfR: PROC [r: REF ANY] RETURNS [tv: AMTypes.TypedVariable] =
TRUSTED {tv ← AMBridge.TVForReferent[r]};
UnParseTree: ViewRec.UnParseProc =
BEGIN
AMTypes.Assign[lhs: treeAsTV, rhs: tv];
asRope ← Trees.Format[who: treeAsTree^, style: Algebraic];
END;
MaxTree: ViewRec.MaxProc =
{RETURN [lines: 2, maxWidthNeeded: 1024]};
RecognizeTree: ViewRec.Recognizer =
{RETURN [TRUE, treeHandler, NIL]};
UnParseTreeNodeList: ViewRec.UnParseProc =
BEGIN
AMTypes.Assign[lhs: tnlAsTV, rhs: tv];
asRope ← NIL;
FOR tnl: TreeNodeList ← tnlAsTNL^, tnl.rest WHILE tnl # NIL DO
this: ROPE ← Trees.Format[who: tnl.first, style: Algebraic];
asRope ← IF asRope = NIL THEN this ELSE asRope.Cat[", ", this];
ENDLOOP;
asRope ← Rope.Cat["(", asRope, ")"];
END;
MaxTreeNodeList: ViewRec.MaxProc =
{RETURN [lines: 3, maxWidthNeeded: 1024]};
RecognizeTreeNodeList: ViewRec.Recognizer =
{RETURN [TRUE, treeNodeListHandler, NIL]};
UnParseST: ViewRec.UnParseProc =
BEGIN
EatIt: PROC [asAny: REF ANY] RETURNS [abort: BOOLEAN] =
BEGIN
nc: NamedCondition ← NARROW[asAny];
abort ← FALSE;
IF asRope # NIL THEN asRope ← asRope.Concat["\n"];
asRope ← asRope.Cat[nc.name, "(", IF nc.posted THEN "p" ELSE ""].Cat[
IF nc.postedIncrementally THEN "i" ELSE "", "): ",
Trees.Format[who: nc.cond, style: Algebraic]];
END;
AMTypes.Assign[lhs: stAsTV, rhs: tv];
asRope ← NIL;
stAsST^.EnumerateIncreasing[EatIt];
END;
MaxST: ViewRec.MaxProc =
{RETURN [lines: 5, maxWidthNeeded: 1024]};
RecognizeST: ViewRec.Recognizer =
{RETURN [TRUE, stHandler, NIL]};
CompareNamedConditions: OrderedSymbolTableRef.CompareProc =
BEGIN
k1, k2: ROPE;
k1 ← WITH r1 SELECT FROM
nc: NamedCondition => nc.name,
r: ROPE => r,
ENDCASE => ERROR;
k2 ← WITH r2 SELECT FROM
nc: NamedCondition => nc.name,
r: ROPE => r,
ENDCASE => ERROR;
RETURN [k1.Compare[k2]];
END;
Pack: PROC [display: Display] = {
IF display.mucking > 0 THEN display.rv.DisplayMessage["Not now"]
ELSE HierarchicalDisplays.Pack[display.rootDisplay]};
LookForChange: HierarchicalDisplays.ChildNotifyProc--PROC [child: Child]-- =
BEGIN
WITH child SELECT FROM
leaf: HierarchicalDisplays.Leaf => IF ISTYPE[leaf.instanceData, NodeElt] THEN BEGIN
ne: NodeElt ← NARROW[leaf.instanceData];
IF NOT ne.changed THEN RETURN;
ne.changed ← FALSE;
SELECT ne.parent.display.ctlPanel.mode FROM
Value => BEGIN
ViewerTools.SetContents[leaf.value, FormatNE[ne]];
leaf.value.newVersion ← FALSE;
IF ne.badString THEN
BEGIN
Buttons.SetDisplayStyle[button: leaf.nameButton, style: $BlackOnWhite];
ne.badString ← FALSE;
END;
END;
Test => NULL;
ENDCASE => ERROR;
END;
in: HierarchicalDisplays.InternalNode => BEGIN
cb: CellBrowser ← NARROW[in.instanceData];
IF cb.changed THEN
BEGIN
Buttons.SetDisplayStyle[
child.nameButton,
IF cb.cell.realCellStuff.schedNext = RoseTypes.notInCellList
THEN $BlackOnWhite
ELSE IF cb.cell = cb.cell.parent.CellToStr[].schedFirst
THEN $WhiteOnBlack
ELSE $BlackOnGrey];
cb.changed ← FALSE;
END;
END;
ENDCASE => ERROR;
END;
LookForChanges: SAFE PROC [] =
CHECKED BEGIN
HierarchicalDisplays.EnumerateChildren[LookForChange];
END;
longing: INTEGER ← 0;
NoticeStart: ENTRY RoseEvents.NotifyProc =
{IF (longing ← longing + 1) > 0 THEN trackChanges ← longIncremental};
NoticeStop: ENTRY RoseEvents.NotifyProc =
{IF (longing ← longing - 1) < 1 AND NOT trackChanges THEN
{LookForChanges[]; trackChanges ← TRUE}};
NoticeDisplayStart: ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Running};
NoticeDisplayInterrupt: ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Interrupted};
NoticeDisplayStop: ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Idle};
activityNames: ARRAY LogSubject OF LIST OF ATOM = [
nodeValueChanges: LIST[$ChangeEarly],
switchComputationSteps: LIST[$Perturbed, $Found, $NewNodeQ, $NewNodeUD]
];
LoggingNotify: ENTRY PROC [clientData: REF ANY] --ViewRec.NotifyClientProc-- =
BEGIN
display: Display ← NARROW[clientData];
logging: Logging ← display.ctlPanel.logging;
FOR ls: LogSubject IN LogSubject DO
IF logging[ls] # display.logging[ls] THEN {
FOR la: LIST OF ATOM ← activityNames[ls], la.rest WHILE la # NIL DO
(IF logging[ls] THEN RoseEvents.AddWatcher ELSE RoseEvents.RemoveWatcher)[
event: la.first,
watcher: [NotifyActivity, display],
watched: RoseEvents.all
];
ENDLOOP;
display.logging[ls] ← logging[ls];
};
ENDLOOP;
END;
NotifyActivity: PUBLIC PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- =
BEGIN
display: Display ← NARROW[watcherData];
node: Node ← NARROW[watched];
agitator: RoseTypes.Slot ← IF arg = NIL THEN RoseTypes.nilSlot ELSE NARROW[arg, RoseRun.SlotRef]^;
agName: ROPEIF agitator # RoseTypes.nilSlot
THEN Rope.Cat[
RoseCreate.LongCellName[agitator.cell],
".",
agitator.cell.realCellStuff.effectivePorts[agitator.effectivePortIndex].name
]
ELSE NIL;
nodeName: ROPE ← RoseCreate.LongNodeName[node];
fmtName, opName: ROPENIL;
fmt: RoseTypes.Format ← NIL;
SELECT event FROM
$ChangeEarly, $ChangeLate => {fmtName ← ""; opName ← "←"};
$Perturbed => opName ← "Perturbed";
$Found => opName ← "Found";
$NewNodeQ => {opName ← "←Q"; IF node.significances[inImpl] THEN fmtName ← "QUD"};
$NewNodeUD => {opName ← "←UD"; IF node.significances[inImpl] THEN fmtName ← "QUD"};
ENDCASE => ERROR;
display.log.PutRope[nodeName.Cat[" ", opName]];
IF fmtName # NIL THEN fmt ← node.type.procs.GetFormat[node.type, fmtName];
IF fmt # NIL THEN display.log.PutRope[Rope.Cat[" ", fmt.FormatValue[node, fmt, node.valPtr]]];
IF agName # NIL THEN display.log.PutRope[Rope.Cat[" by ", agName]];
display.log.PutRope["\n"];
END;
IncrNotify: ENTRY SAFE PROC [clientData: REF ANY] --ViewRec.NotifyClientProc-- =
CHECKED BEGIN
display: Display ← NARROW[clientData];
IF display.ctlPanel.incrementalDisplay = longIncremental THEN RETURN;
longIncremental ← display.ctlPanel.incrementalDisplay;
IF longing > 0 AND trackChanges # longIncremental THEN
{IF (trackChanges ← longIncremental) THEN LookForChanges[]};
RoseEvents.Notify[event: setIncrementalDisplay, handleAborted: TRUE];
END;
longIncremental: BOOLEANFALSE;
trackChanges: BOOLEANTRUE;
setIncrementalDisplay: ATOM ← Atom.MakeAtom["Spreitzer January 6, 1984 9:19 pm"];
NoticeSetIncrementalDisplay: RoseEvents.NotifyProc =
CHECKED BEGIN
display: Display ← NARROW[watcherData];
display.ctlPanel.incrementalDisplay ← longIncremental;
END;
TiogaNoticeEdit: PROC [viewer: Viewer ← NIL] RETURNS [recordAtom: BOOLTRUE, quit: BOOLFALSE] --TiogaOps.CommandProc-- =
BEGIN
asAny: REF ANY ← ViewerOps.FetchProp[viewer: viewer, prop: leafProp];
IF (IF asAny = NIL THEN TRUE ELSE NOT ISTYPE[asAny, HierarchicalDisplays.Leaf]) THEN RETURN [recordAtom: FALSE, quit: FALSE];
recordAtom ← FALSE; quit ← TRUE;
[] ← NoticeEdit[NARROW[asAny]];
END;
NoticeEdit: PROC [leaf: HierarchicalDisplays.Leaf] RETURNS [success: BOOLEAN] =
BEGIN
ne: NodeElt ← NARROW[leaf.instanceData];
SELECT ne.parent.display.ctlPanel.mode FROM
Value => BEGIN
ts: IO.STREAM;
IF ne.node.valPtr = RoseTypes.nilPtr THEN ERROR;
ViewerTools.InhibitUserEdits[leaf.value];
ts ← IO.RIS[ViewerTools.GetContents[leaf.value]];
success ← ne.format.ParseValue[ne.node, ne.format, NCOPtr[ne.node, ne.org.circ], ts];
ts.Close[];
IF success THEN RoseRun.ValueChanged[ne.node];
Buttons.SetDisplayStyle[leaf.nameButton, IF success THEN $BlackOnWhite ELSE $WhiteOnBlack];
IF success THEN
BEGIN
leaf.value.newVersion ← FALSE;
--VT.SetContents[leaf.value, ne.format.FormatValue[ne.node.type, ne.format, wp]];--
END;
ViewerTools.EnableUserEdits[leaf.value];
IF NOT success THEN leaf.value.newVersion ← TRUE;
END;
Test => BEGIN
test: RoseTypes.NodeTest;
ts: IO.STREAM;
ViewerTools.InhibitUserEdits[leaf.value];
ts ← IO.RIS[ViewerTools.GetContents[leaf.value]];
[success, test] ← ne.format.ParseTest[ne.node.type, ne.format, ts];
ts.Close[];
Buttons.SetDisplayStyle[leaf.nameButton, IF success THEN $BlackOnWhite ELSE $WhiteOnBlack];
IF success THEN
BEGIN
ne.test ← test;
--VT.SetContents[leaf.value, ne.format.FormatTest[ne.node.type, ne.format, tp, td]];--
leaf.value.newVersion ← FALSE;
END;
ViewerTools.EnableUserEdits[leaf.value];
IF NOT success THEN leaf.value.newVersion ← TRUE;
END;
ENDCASE => ERROR;
ne.badString ← NOT success;
END;
FormatNE: PUBLIC PROC [ne: NodeElt] RETURNS [rope: ROPE] = {
rope ← SELECT ne.org.display.ctlPanel.mode FROM
Value => ne.format.FormatValue[
ne.node,
ne.format,
NCOPtr[ne.node, ne.org.circ]],
Test => ne.format.FormatTest[
ne.node.type,
ne.format,
ne.test],
ENDCASE => ERROR;
};
NCOPtr: PUBLIC PROC [n: Node, nco: NodeCircuitOrigin] RETURNS [p: Ptr] =
{p ← n.valPtr};
NoticeEdits: PROC [display: Display] RETURNS [AOK: BOOLEAN] =
BEGIN
Notice: HierarchicalDisplays.ChildNotifyProc =
BEGIN
IF NOT NoticeEdit[NARROW[child]] THEN AOKFALSE;
END;
AOKTRUE;
HierarchicalDisplays.EnumerateChildren[to: Notice, internals: FALSE, changedOnly: TRUE];
END;
Interrupt: PROC [display: Display] = {RoseRun.stop ← TRUE};
Disable: PROC [display: Display] RETURNS [ok: BOOL] =
BEGIN
fh: PrincOps.FrameHandle ← display.stopped;
ok ← (fh # NIL) AND RoseRun.DisableThisStop[fh];
END;
Proceed: PROC [display: Display] =
BEGIN
Inner: ENTRY PROC = {
display.stopResponse ← Resume;
display.ctlPanel.status ← Running;
BROADCAST display.notice;
};
IF NoticeEdits[display] THEN Inner[];
END;
Abort: PROC [display: Display] =
BEGIN
Inner: ENTRY PROC = {
display.stopResponse ← Abort;
display.ctlPanel.status ← Running;
BROADCAST display.notice;
};
IF NoticeEdits[display] THEN Inner[];
END;
GetStopResponse: PROC [display: Display, msg: ROPE, data: REF ANY] RETURNS [sr: StopResponse] =
BEGIN
RoseEvents.Notify[event: $Interrupt, handleAborted: TRUE];
sr ← ReallyGetStopResponse[display, msg, data];
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
END;
ReallyGetStopResponse: ENTRY PROC [display: Display, msg: ROPE, data: REF ANY] RETURNS [sr: StopResponse] =
BEGIN ENABLE UNWIND => {};
IF display.ctlPanel.status # Interrupted THEN ERROR;
TRUSTED {display.stopped ← PrincOpsUtils.MyLocalFrame[]};
display.rv.DisplayMessage[msg];
WHILE display.ctlPanel.status = Interrupted DO
WAIT display.notice;
ENDLOOP;
RoseRun.stop ← FALSE;
sr ← display.stopResponse;
display.stopped ← NIL;
END;
Run: PROC [display: Display] =
BEGIN
IF NOT NoticeEdits[display] THEN RETURN;
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
BEGIN ENABLE
BEGIN
RoseTypes.Stop =>
BEGIN
SELECT GetStopResponse[display, msg, data] FROM
Resume => RESUME;
Abort => ERROR ABORTED;
ENDCASE => ERROR;
END;
UNWIND => RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
IF display.type = Ordinary THEN RoseRun.Run[display.sim] ELSE RoseRun.Test[sim: display.sim, parms: display.parms];
END;
RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
SingleStep: PROC [display: Display] RETURNS [stepType: RoseRun.StepType] =
BEGIN
IF display.type = Test
THEN {display.rv.DisplayMessage["Can't single-step a CellTest"]; RETURN};
IF NOT NoticeEdits[display] THEN RETURN;
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
stepType ← RoseRun.StepSim[display.sim
!RoseTypes.Stop =>
BEGIN
SELECT GetStopResponse[display, msg, data] FROM
Resume => RESUME;
Abort => ERROR ABORTED;
ENDCASE => ERROR;
END;
UNWIND => RoseEvents.Notify[event: $Stop, handleAborted: TRUE]];
RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
PathNameToPath: PROC [pathName: ROPE] RETURNS [path: LIST OF ROPE] =
BEGIN
dotIndex: INT;
last: LIST OF ROPELIST[pathName];
path ← last;
WHILE (dotIndex ← last.first.Find["."]) >= 0 DO
last.rest ← LIST[last.first.Substr[dotIndex+1, last.first.Length[] - (dotIndex+1)]];
last.first ← last.first.Substr[0, dotIndex];
last ← last.rest;
ENDLOOP;
END;
SetMode: PROC [display: Display, mode: DisplayMode] =
BEGIN
SetValue: HierarchicalDisplays.ChildNotifyProc =
BEGIN
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
WITH leaf.instanceData SELECT FROM
ne: NodeElt => BEGIN
val: ROPE ← FormatNE[ne];
ViewerTools.InhibitUserEdits[leaf.value];
ViewerTools.SetContents[leaf.value, val];
leaf.value.newVersion ← FALSE;
ViewerTools.EnableUserEdits[leaf.value];
Buttons.SetDisplayStyle[leaf.nameButton, $BlackOnWhite];
ne.badString ← FALSE;
END;
cs: CellState => NULL;
ENDCASE => ERROR;
END;
SetTest: HierarchicalDisplays.ChildNotifyProc =
BEGIN
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
WITH leaf.instanceData SELECT FROM
ne: NodeElt => BEGIN
val: ROPE ← ne.format.FormatTest[ne.node.type, ne.format, ne.test];
ViewerTools.InhibitUserEdits[leaf.value];
ViewerTools.SetContents[leaf.value, val];
leaf.value.newVersion ← FALSE;
ViewerTools.EnableUserEdits[leaf.value];
Buttons.SetDisplayStyle[leaf.nameButton, $BlackOnWhite];
ne.badString ← FALSE;
END;
cs: CellState => NULL;
ENDCASE => ERROR;
END;
HierarchicalDisplays.EnumerateChildren[to: IF mode = Value THEN SetValue ELSE SetTest, internals: FALSE];
END;
ModeNotify: ViewRec.NotifyClientProc =
{display: Display ← NARROW[clientData];
SetMode[display, display.ctlPanel.mode]};
ClearStack: PROC [display: Display] =
{display.ctlPanel.conditionStack ← NIL};
ClearCondition: PROC [display: Display] =
{display.ctlPanel.condition ← NIL};
GetCondition: PROC [display: Display] RETURNS [nc: NamedCondition] =
BEGIN
name: ROPE ← ViewerTools.GetSelectionContents[];
asAny: REF ANY;
IF name.Length[] < 1 THEN RETURN [NIL];
asAny ← display.ctlPanel.conditions.Lookup[name];
nc ← NARROW[asAny];
END;
PostCondition: PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF nc.posted THEN {display.rv.DisplayMessage["Already posted!"]; RETURN};
nc.posted ← TRUE;
RoseConditions.PostOnSettle[
sim: display.sim,
condition: nc.cond];
ViewRec.RedisplayElt[display.conditionsHandle];
END;
RemoveCondition: PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
RoseConditions.UnPostOnSettle[
sim: display.sim,
condition: nc.cond];
nc.posted ← FALSE;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
PostIncremental: PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF nc.postedIncrementally THEN {display.rv.DisplayMessage["Already posted incrementally!"]; RETURN};
nc.postedIncrementally ← TRUE;
nc.ic ← RoseConditions.PostIncrementally[nc.cond];
ViewRec.RedisplayElt[display.conditionsHandle];
END;
RemoveIncremental: PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF NOT nc.postedIncrementally THEN {display.rv.DisplayMessage["Not posted incrementally!"]; RETURN};
RoseConditions.UnPostIncrementally[nc.ic];
nc.ic ← NIL;
nc.postedIncrementally ← FALSE;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
AddNamedCondition: PROC [display: Display, name: ROPE] =
BEGIN
nc: NamedCondition;
nc ← NEW [NamedConditionRep ← [
name: name,
cond: display.ctlPanel.condition]];
IF nc.cond = NIL THEN {display.rv.DisplayMessage["empty condition!"]; RETURN};
IF name.Length[] < 1 THEN {display.rv.DisplayMessage["empty name!"]; RETURN};
IF display.ctlPanel.conditions.Lookup[name] # NIL THEN {display.rv.DisplayMessage["already exists!"]; RETURN};
display.ctlPanel.conditions.Insert[nc];
display.ctlPanel.condition ← NIL;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
DeleteNamedCondition: PROC [display: Display, name: ROPE ] =
BEGIN
old: REF ANY;
IF name.Length[] < 1 THEN {display.rv.DisplayMessage["empty name!"]; RETURN};
IF display.ctlPanel.conditions.Lookup[name] = NIL THEN {display.rv.DisplayMessage["not found"]; RETURN};
IF (old ← display.ctlPanel.conditions.Delete[name]) = NIL THEN ERROR;
END;
MakeInterface: PROC [sim: RoseTypes.Simulation] = {
[] ← BrowseDisplay[
display: NewDisplay[sim, [iconic: FALSE]],
info: [iconic: FALSE]
];
};
NewDisplay: PUBLIC PROC [sim: RoseTypes.Simulation, info: ViewerClasses.ViewerRec ← [], paint: BOOLEANTRUE] RETURNS [display: Display] =
BEGIN
OtherStuff: ViewRec.OtherStuffProc--PROC [in: Viewer] RETURNS [stuff: LIST OF Viewer]-- =
BEGIN
stuff ← IF display.type = Test
THEN LIST[ViewRec.RVQuaViewer[ViewRec.ViewRef[
agg: display.parms ← NEW [RoseRun.TestParmsRep ← []],
createOptions: [mayInitiateRelayout: FALSE, feedBackHeight: 0],
viewerInit: [parent: in],
paint: FALSE]]]
ELSE NIL;
END;
rvv: Viewer;
ctlPanel: ControlPanel ← NEW [ControlPanelRep ← [
conditions: OrderedSymbolTableRef.CreateTable[CompareNamedConditions],
incrementalDisplay: longIncremental,
Pack: Pack,
NoticeEdits: NoticeEdits,
Run: Run,
SingleStep: SingleStep,
Interrupt: Interrupt,
Disable: Disable,
Proceed: Proceed,
Abort: Abort,
ClearStack: ClearStack,
ClearCondition: ClearCondition,
Or: Or,
PostCondition: PostCondition,
RemoveCondition: RemoveCondition,
PostIncremental: PostIncremental,
RemoveIncremental: RemoveIncremental,
AddNamedCondition: AddNamedCondition,
DeleteNamedCondition: DeleteNamedCondition,
Save: Save,
Restore: Restore]];
display ← NEW [DisplayRep ← [
sim: sim,
rootCell: sim.root,
cth: sim.cth,
type: IF sim.cth = NIL THEN Ordinary ELSE Test,
ctlPanel: ctlPanel,
log: ViewerIO.CreateViewerStreams[name: sim.root.name.Concat[" log"]].out,
conditionHandle: NIL,
conditionsHandle: NIL,
rootDisplay: HierarchicalDisplays.CreateRoot[
viewerInit: [
parent: NIL,
iconic: FALSE,
scrollable: TRUE,
name: sim.root.name.Cat[".display"],
icon: displayIcon
],
paint: paint],
rv: NIL]];
display.rv ← ViewRec.ViewRef[
agg: ctlPanel,
specs: ViewRec.BindingListAppend[
LIST[
["mode", Notify[notify: ModeNotify, clientData: display]],
["incrementalDisplay", Notify[notify: IncrNotify, clientData: display]],
["logging", Group[sublist: LIST[
[NEW [INT ← 1], Notify[notify: LoggingNotify, clientData: display]],
[NEW [INT ← 2], Notify[notify: LoggingNotify, clientData: display]]]]],
["conditionStack", TryRecognizer[RecognizeTreeNodeList]],
["condition", TryRecognizer[RecognizeTree]],
["conditions", TryRecognizer[RecognizeST]],
["status", Value[val: NIL, visible: TRUE, dontAssign: TRUE]] ] ,
ViewRec.BindAllOfATypeFromRefs[rec: ctlPanel, handle: NEW [Display ← display]] ],
otherStuff: OtherStuff,
createOptions: [maxEltsHeight: 100, exclusiveProcs: FALSE],
viewerInit: [parent: NIL, iconic: FALSE, scrollable: TRUE, name: sim.root.name.Cat[".ops"]],
paint: paint];
rvv ← ViewRec.RVQuaViewer[display.rv];
display.conditionHandle ← display.rv.GetEltHandle[LIST["condition"]];
display.conditionsHandle ← display.rv.GetEltHandle[LIST["conditions"]];
TRUSTED {Process.InitializeCondition[condition: @display.notice, ticks: Process.SecondsToTicks[5]]};
RoseEvents.AddWatcher[event: setIncrementalDisplay, watcher: [NoticeSetIncrementalDisplay, display]];
RoseEvents.AddWatcher[event: $Stop, watcher: [NoticeDisplayStop, display]];
RoseEvents.AddWatcher[event: $Interrupt, watcher: [NoticeDisplayInterrupt, display]];
RoseEvents.AddWatcher[event: $Start, watcher: [NoticeDisplayStart, display]];
END;
cellClass: PUBLIC HierarchicalDisplays.ChildClass ← NEW [HierarchicalDisplays.ChildClassRep ← [
buttonProc: DullButtonProc,
NotifyOnRemove: NoticeCellRemoval]];
nodeClass: PUBLIC HierarchicalDisplays.ChildClass ← NEW [HierarchicalDisplays.ChildClassRep ← [
buttonProc: DullButtonProc,
NotifyOnRemove: NoticeNodeRemoval]];
DullButtonProc: Buttons.ButtonProc =
BEGIN
leaf: HierarchicalDisplays.Leaf;
ne: NodeElt;
IF (IF clientData = NIL THEN TRUE ELSE NOT ISTYPE[clientData, HierarchicalDisplays.Leaf]) THEN
BEGIN
MessageWindow.Append[message: "Don't do that", clearFirst: TRUE];
RETURN;
END;
leaf ← NARROW[clientData];
ne ← NARROW[leaf.instanceData];
SELECT mouseButton FROM
red => ViewerTools.SetSelection[leaf.value];
yellow => IF control THEN SetFormat[ne, leaf] ELSE AddAnd[ne, shift];
blue => IF control THEN TellFormat[ne] ELSE AddOr[ne, shift];
ENDCASE => ERROR;
END;
TellFormat: PROC [ne: NodeElt] =
BEGIN
ne.org.display.rv.DisplayMessage[ViewRec.clearMessagePlace];
ne.org.display.rv.DisplayMessage[IO.PutFR[
"Current format is %g, choices are %g",
IO.refAny[ne.format.key],
IO.refAny[ne.node.type.procs.ListFormats[ne.node.type]]]];
oldFmtKey ← oldFmtKey;
END;
oldFmtKey: ROPE ← "?there was no old format key?";
SetFormat: PROC [ne: NodeElt, leaf: HierarchicalDisplays.Leaf] =
BEGIN
fmtKey: ROPE ← ViewerTools.GetSelectionContents[];
fmt: RoseTypes.Format;
IF fmtKey.Length[] = 0 THEN fmtKey ← oldFmtKey;
fmt ← ne.node.type.procs.GetFormat[ne.node.type, fmtKey];
IF fmt # NIL THEN {
ne.format ← fmt;
TellFormat[ne];
NotifyNodeView[$NewFormat, ne.node, leaf, NIL];
ViewerOps.MoveViewer[viewer: leaf.value,
x: leaf.value.wx, y: leaf.value.wy,
w: ne.format.MaxWidth[ne.node.type, ne.format, VFonts.defaultFont] + 20,
h: leaf.value.wh, paint: FALSE];
}
ELSE {
ne.org.display.rv.DisplayMessage[ViewRec.clearMessagePlace];
ne.org.display.rv.DisplayMessage[IO.PutFR[
"Format %g unrecognized",
IO.refAny[fmtKey]]]};
oldFmtKey ← fmtKey;
END;
AddOr: PROC [ne: NodeElt, invert: BOOLEAN] =
BEGIN
display: Display ← ne.org.display;
nt: RoseConditions.NodeTester ← NEW [RoseConditions.NodeTesterRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
test: ne.test]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.test.proc = NIL THEN {display.rv.DisplayMessage["invalid test"]; RETURN};
IF invert THEN leaf ← Trees.Not[leaf];
Push[display, Pop[display].Or[display.ctlPanel.condition]];
display.ctlPanel.condition ← leaf;
END;
AddAnd: PROC [ne: NodeElt, invert: BOOLEAN] =
BEGIN
display: Display ← ne.org.display;
nt: RoseConditions.NodeTester ← NEW [RoseConditions.NodeTesterRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
test: ne.test]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.test.proc = NIL THEN {display.rv.DisplayMessage["invalid test"]; RETURN};
IF invert THEN leaf ← Trees.Not[leaf];
display.ctlPanel.condition ← Trees.And[display.ctlPanel.condition, leaf];
ViewRec.RedisplayElt[display.conditionHandle];
END;
NoticeCellRemoval: HierarchicalDisplays.ChildNotifyProc =
BEGIN
cb: CellBrowser ← NARROW[child.instanceData];
cb.cell.other ← Asserting.AssertFn1[fn: cb.display, val: NIL, inAdditionTo: cb.cell.other];
IF cb.cell.substantiality = Real THEN RoseEvents.RemoveWatcher[watched: cb.cell, event: $Schedule, watcher: [NotifyCellView, child]];
END;
NoticeNodeRemoval: HierarchicalDisplays.ChildNotifyProc =
BEGIN
ne: NodeElt ← NARROW[child.instanceData];
displays: NodeDisplayList ← NARROW[Asserting.FnVal[fn: nodeDisplaysProp, from: ne.node.other]];
nd: NodeDisplay;
found: BOOLEAN;
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
[displays, nd, found] ← NDLSearch[ndl: displays, org: ne.org, remove: TRUE];
IF (IF found THEN nd.dc # child ELSE TRUE) THEN ERROR;
ne.node.other ← Asserting.AssertFn1[fn: nodeDisplaysProp, val: displays, inAdditionTo: ne.node.other];
RoseEvents.RemoveWatcher[watched: ne.node, watcher: [NotifyNodeView, leaf], event: $ChangeEarly];
END;
NotifyNodeView: PUBLIC RoseEvents.NotifyProc =
BEGIN
node: Node ← NARROW[watched];
leaf: HierarchicalDisplays.Leaf ← NARROW[watcherData];
ne: NodeElt ← NARROW[leaf.instanceData];
v: Viewer ← leaf.value;
val: ROPE;
IF ne.org.display.ctlPanel.mode # Value THEN RETURN;
IF NOT trackChanges THEN {ne.changed ← TRUE; RETURN};
IF ne.badString THEN
BEGIN
Buttons.SetDisplayStyle[button: leaf.nameButton, style: $BlackOnWhite];
ne.badString ← FALSE;
END;
val ← FormatNE[ne];
ViewerTools.SetContents[v, val];
END;
NotifyCellView: PUBLIC RoseEvents.NotifyProc =
BEGIN
cell: Cell ← NARROW[watched];
dc: HierarchicalDisplays.Child ← NARROW[watcherData];
IF trackChanges THEN Buttons.SetDisplayStyle[dc.nameButton, IF cell.realCellStuff.schedNext = RoseTypes.notInCellList THEN $BlackOnWhite ELSE IF cell = cell.parent.CellToStr[].schedFirst THEN $WhiteOnBlack ELSE $BlackOnGrey]
ELSE NARROW[dc.instanceData, CellBrowser].changed ← TRUE;
END;
Or: PROC [display: Display] =
{display.ctlPanel.condition ← Pop[display].Or[display.ctlPanel.condition]};
Push: PUBLIC PROC [display: Display, cond: Condition] =
{display.ctlPanel.conditionStack ← CONS[cond, display.ctlPanel.conditionStack]};
Pop: PUBLIC PROC [display: Display] RETURNS [cond: Condition] =
BEGIN
IF display.ctlPanel.conditionStack = NIL THEN RETURN [NIL];
cond ← display.ctlPanel.conditionStack.first;
display.ctlPanel.conditionStack ← display.ctlPanel.conditionStack.rest;
END;
Save: PROC [display: Display, fileName: ROPE] RETURNS [errMsg: ROPE] =
{IF NOT NoticeEdits[display] THEN RETURN ["Invalid edits not yet fixed"];
TRUSTED {errMsg ← RoseStateIO.Save[display.rootCell, fileName]}};
Restore: PROC [display: Display, fileName: ROPE] RETURNS [errMsg: ROPE] =
TRUSTED {errMsg ← RoseStateIO.Restore[display.rootCell, fileName]};
Setup: PROC =
BEGIN
TiogaOps.RegisterCommand[name: $InsertLineBreak, proc: TiogaNoticeEdit];
RoseEvents.AddWatcher[event: $Stop, watcher: [NoticeStop]];
RoseEvents.AddWatcher[event: $Interrupt, watcher: [NoticeStop]];
RoseEvents.AddWatcher[event: $Start, watcher: [NoticeStart]];
END;
Setup[];
END.