<> <> <> <> 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: BOOLEAN _ FALSE ]; 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: ROPE _ IF 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: ROPE _ NIL; 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: BOOLEAN _ FALSE; trackChanges: BOOLEAN _ TRUE; 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: BOOL _ TRUE, quit: BOOL _ FALSE] --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 AOK _ FALSE; END; AOK _ TRUE; 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 ROPE _ LIST[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: BOOLEAN _ TRUE] 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.