<> <> <> <> DIRECTORY AMBridge, AMTypes, Asserting, Atom, Buttons, HierarchicalDisplays, IO, Labels, MessageWindow, OrderedSymbolTableRef, PrincOps, PrincOpsUtils, Process, Rope, RoseConditions, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerClasses, ViewerIO, ViewerOps, ViewerTools, ViewRec; RoseDisplayOps: CEDAR MONITOR IMPORTS AMBridge, AMTypes, Asserting, Atom, Buttons, HierarchicalDisplays, IO, MessageWindow, OrderedSymbolTableRef, PrincOpsUtils, Process, Rope, RoseConditions, 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 ]; 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, ne.format.FormatValue[ ne.node, ne.format, ne.node.ValWP[]]]; 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}; activityName: ARRAY LogSubject OF ATOM = [$SimpleChanged, $NewSpecialSwitchInstructions, $SwitchChanged]; LoggingNotify: ENTRY SAFE PROC [clientData: REF ANY] --ViewRec.NotifyClientProc-- = CHECKED BEGIN display: Display _ NARROW[clientData]; logging: Logging _ display.ctlPanel.logging; FOR ls: LogSubject IN LogSubject DO IF logging[ls] # display.logging[ls] THEN { IF logging[ls] THEN RoseEvents.AddWatcher[activityName[ls], [NotifyActivity, display]] ELSE RoseEvents.RemoveWatcher[activityName[ls], [NotifyActivity, display]]; display.logging[ls] _ logging[ls]; }; ENDLOOP; END; NotifyActivity: SAFE PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- = CHECKED BEGIN display: Display _ NARROW[watcherData]; ar: RoseRun.ActivityReport _ NARROW[arg]; IF ar.socket.cell # NIL THEN display.log.PutF["(%g=)", IO.rope[LongName[ar.socket.cell].Cat[".", ar.socket.cell.type.ports[ar.socket.index].name]]]; display.log.PutRope[LongName[ar.node.cellIn].Cat[".", ar.node.name]]; SELECT event FROM $SimpleChanged => { fmt: RoseTypes.Format _ ar.node.type.procs.GetFormat[ar.node.type, ""]; display.log.PutF[" _ %g\n", IO.rope[fmt.FormatValue[ar.node, fmt, RoseTypes.SocketToWP[ar.socket]]]]; }; $SwitchChanged => { fmt: RoseTypes.Format _ ar.node.type.procs.GetFormat[ar.node.type, ""]; display.log.PutF[" _ %g\n", IO.rope[fmt.FormatValue[ar.node, fmt, NIL]]]; }; $NewSpecialSwitchInstructions => display.log.PutRope[" got new instructions\n"]; ENDCASE => ERROR; END; LongName: PROC [cell: Cell] RETURNS [ln: ROPE] = { ln _ cell.name; FOR cell _ cell.parent, cell.parent WHILE cell # NIL DO ln _ cell.name.Cat[".", ln]; ENDLOOP}; NotifyNodeQ: PUBLIC PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- = BEGIN node: Node _ NARROW[watched]; cell: Cell _ NARROW[arg]; display: Display _ NARROW[watcherData]; fmt: RoseTypes.Format _ node.type.procs.GetFormat[node.type, "QUD"]; IF event # $NewNodeQ THEN ERROR; display.log.PutF["New Q for %g", IO.rope[LongName[node.cellIn].Cat[".", node.name]]]; IF cell # NIL THEN display.log.PutF[" from %g", IO.rope[LongName[cell]]]; IF fmt # NIL THEN display.log.PutF[": %g", IO.rope[fmt.FormatValue[node, fmt, NIL]]]; display.log.PutRope["\n"]; END; NotifyNodeUD: PUBLIC PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- = BEGIN node: Node _ NARROW[watched]; cell: Cell _ NARROW[arg]; display: Display _ NARROW[watcherData]; fmt: RoseTypes.Format _ node.type.procs.GetFormat[node.type, "QUD"]; IF event # $NewNodeUD THEN ERROR; display.log.PutF["New UD for %g", IO.rope[LongName[node.cellIn].Cat[".", node.name]]]; IF cell # NIL THEN display.log.PutF[" from %g", IO.rope[LongName[cell]]]; IF fmt # NIL THEN display.log.PutF[": %g", IO.rope[fmt.FormatValue[node, fmt, NIL]]]; display.log.PutRope["\n"]; END; NotifyPerturb: PUBLIC PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- = BEGIN node: Node _ NARROW[watched]; cell: Cell _ NARROW[arg]; display: Display _ NARROW[watcherData]; IF event # $Perturbed THEN ERROR; display.log.PutRope[LongName[node.cellIn].Cat[".", node.name, " perturbed"]]; IF cell # NIL THEN display.log.PutF[" by %g", IO.rope[LongName[cell]]]; display.log.PutRope["\n"]; END; NotifyFound: PUBLIC PROC [event: ATOM, watched, watcherData, arg: REF ANY] --RoseEvents.NotifyProc-- = BEGIN node: Node _ NARROW[watched]; cell: Cell _ NARROW[arg]; display: Display _ NARROW[watcherData]; IF event # $Found THEN ERROR; display.log.PutRope[LongName[node.cellIn].Cat[".", node.name, " Found"]]; IF cell # NIL THEN display.log.PutF[" from %g", IO.rope[LongName[cell]]]; 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: TiogaOps.CommandProc --PROC [viewer: Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE]-- = 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 ModifyIt: RoseRun.ModifyProc--PROC [cell: Cell] RETURNS [subtle: BOOLEAN _ FALSE]-- = BEGIN ts: IO.STREAM _ IO.RIS[ViewerTools.GetContents[leaf.value]]; wp _ ne.node.ValWP[]; success _ ne.format.ParseValue[ne.node, ne.format, wp, ts]; ts.Close[]; END; wp: RoseTypes.WordPtr; IF ne.node.visible.cell = NIL THEN ERROR; ViewerTools.InhibitUserEdits[leaf.value]; IF ne.node.type.simple THEN RoseRun.AllowToModify[cell: ne.node.visible.cell, modifier: ModifyIt, mayRescheduleSelf: TRUE] ELSE { [] _ ModifyIt[NIL]; 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 tp: RoseTypes.NodeTestProc; td: REF ANY; ts: IO.STREAM; ViewerTools.InhibitUserEdits[leaf.value]; ts _ IO.RIS[ViewerTools.GetContents[leaf.value]]; [success, tp, td] _ 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.testData _ td; ne.testProc _ tp; --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; 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, cth: display.cth, 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 _ ne.format.FormatValue[ne.node, ne.format, ne.node.ValWP[]]; 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.testProc, ne.testData]; 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.PostOnCell[ cell: display.rootCell, 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.UnPostOnCell[ cell: display.rootCell, 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; NewDisplay: PROC [sim: RoseTypes.Simulation, info: ViewerClasses.ViewerRec _ [], cth: RoseTypes.CellTestHandle _ NIL, 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: cth, type: IF 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"]], 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]], [NEW [INT _ 3], 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: [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]]]]; END; SetFormat: PROC [ne: NodeElt, leaf: HierarchicalDisplays.Leaf] = BEGIN fmtKey: ROPE _ ViewerTools.GetSelectionContents[]; fmt: RoseTypes.Format _ 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]]]}; END; AddOr: PROC [ne: NodeElt, invert: BOOLEAN] = BEGIN display: Display _ ne.org.display; nt: RoseConditions.NodeTest _ NEW [RoseConditions.NodeTestRep _ [ node: ne.node, nodeName: ne.name, nodeFormat: ne.format, cell: ne.org.socket.cell, testData: ne.testData, testProc: ne.testProc]]; leaf: TreeNode _ Trees.Leaf[nt, RoseConditions.test]; IF nt.testProc = 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.NodeTest _ NEW [RoseConditions.NodeTestRep _ [ node: ne.node, nodeName: ne.name, nodeFormat: ne.format, cell: ne.org.socket.cell, testData: ne.testData, testProc: ne.testProc]]; leaf: TreeNode _ Trees.Leaf[nt, RoseConditions.test]; IF nt.testProc = 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 _ ne.format.FormatValue[node, ne.format, node.ValWP[]]; 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.