ProcessMonitorV2.st
changeset 4498 fcebf25e6033
parent 4468 cc786dd7b4cb
child 4501 fe34b74d09ff
--- a/ProcessMonitorV2.st	Mon Jan 27 16:55:49 2003 +0100
+++ b/ProcessMonitorV2.st	Tue Jan 28 12:16:46 2003 +0100
@@ -5,7 +5,11 @@
 		hasSelection selctionRestartable showProcessId showGroup
 		showState showPrio showUsedStack showTotalStack
 		showCurrentSegment showSwitch showWhere currentSortOrder
-		processTable processes showDead sortBlock selectionRestartable'
+		processTable processes showDead sortBlock selectionRestartable
+		updateListDelayTime increaseupdateListDelayTime
+		decreaseupdateListDelayTime updateContentsDelayTime
+		enableDecreaseListDelayTime enableDecreaseContentsDelayTime
+		enableIncreaseListDelayTime enableIncreaseContentsDelayTime'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Monitors-ST/X'
@@ -58,6 +62,25 @@
     "Created: / 14.1.2003 / 11:16:10 / penk"
 ! !
 
+!ProcessMonitorV2 class methodsFor:'instance creation'!
+
+open
+
+    |title answer|
+
+    title := ('ProcessMonitorV2 is in develop right now', Character cr,
+               'to use the old one uncheck [Use new Process Monitor] in', Character cr,
+               'Settings Dialog Tools').
+    answer := Dialog
+                confirm:title
+                title:'Warning' 
+                yesLabel:'Start anyway' noLabel:'Cancel' 
+                initialAnswer:true.
+    answer ifTrue:[
+        ^ super open
+    ].
+! !
+
 !ProcessMonitorV2 class methodsFor:'defaults'!
 
 defaultIcon
@@ -398,12 +421,12 @@
     ^Icon
         constantNamed:#'ProcessMonitorV2 class processSuspend22x22Icon'
         ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(8 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@G@0@@@@@@@@@@@@@@@@@@@@@@@@@@A0L@@@@@@@@@@@@@@@@@
-@@@CA0@@A0TE@P@@A0L@@@@@@@@@@@@@@PTGA0TEAPTGA0TA@@@@@@@@@@@@@@@CAPTEAPTEAPTA@@@@@@@@@@@@@@@@A0TE@0DCAPTE@0@@@@@@@@@@@@@@
-A0TE@0D@@@\EAPTC@@@@@@@@@@@GA0TEAPD@@@@@A0TEAP\C@@@@@@@@@PDEAPTC@@@@@@@@@@@@@P@@@@@@@@@@@0LEAP\@@@@DA@PDA@@@@@@@@@@@@@@C
-APTEA0@DA@PDA@PD@@@@@@@@@@@@A0TEAP@DA@PDA@PDA@P@@@@@@@@@A0TA@0T@A@PDA@PDA@PD@@@@@@@@@@LA@@@G@@PGA0\GA0\GA@@@@@@@@@@@@@@@
-@@@DA@PDA@PDA@P@@@@@@@@@@@@@@@@@A@PDA@PDA@PD@@@@@@@@@@@@@@@@@@@DA@PDA@PD@@@@@@@@@@@@@@@@@@@@@@PDA@PD@@@@@@@@@@@@@@@@@@@@
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 127 127 127 128 0 0 161 161 165 192 0 0 194 194 194 255 192 192 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _9? O??@C?? C??0G??0G??0CO?0@O?0@G? @A?@@@>@@@@@') ; yourself); yourself]
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EA0@@@@@@@@@@@@@@@@@@@@@@@@@@AP\@@@@@@@@@@@@@@@@@
+@@@GAP@@APXFB@@@AP\@@@@@@@@@@@@@B@XEAPXFA XEAPXH@@@@@@@@@@@@@@@GA XFA XFA XH@@@@@@@@@@@@@@@@APXFA0 GA XFA0@@@@@@@@@@@@@@
+APXFA0 @@@TFA XG@@@@@@@@@@@EAPXFA  @@@@@APXFA TG@@@@@@@@B@ FA XG@@TEAPTEAPTEAPTEAPT@@@@@A0\FA TEAPTEAPTEAPTEAPTE@@@@@@@G
+A XFAPTE@@@@@@@@@@@EAP@@@@@@APXFA TEAP@@@@@@@@@@APT@@@@@APXHA0XEAPT@@@@@@@@@@@TE@@@@@@\H@@@EAPTE@@@@@@@@@@@EAP@@@@@@@@@@
+@@TEAP@@@@@@@@@@APT@@@@@@@@@@@@EAPT@@@@@@@@@@@TE@@@@@@@@@@@@APTE@@@@@@@@@@@EAP@@@@@@@@@@@@TEAP@@@@@@@@@@APT@@@@@@@@@@@@E
+APTEAPTEAPTEAPTE@@@@@@@@@@@@APTEAPTEAPTEAPTEAP@a') ; colorMapFromArray:#[0 0 0 128 128 128 160 160 160 195 195 195 220 220 220 255 255 255 194 194 194 161 161 165 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@F@@@O@@COL@G?>@G?>@C?<@C?<@O??@_9? _??<O??<C??<C??<G??<G??<CO?<@O?<@G?<@G?<@G?<@G?<') ; yourself); yourself]
 !
 
 processTerminate22x22Icon
@@ -575,7 +598,7 @@
           #name: 'ProcessMonitorV2'
           #min: #(#Point 10 10)
           #max: #(#Point 1024 768)
-          #bounds: #(#Rectangle 16 42 781 379)
+          #bounds: #(#Rectangle 16 42 807 400)
           #menu: #mainMenu
         )
         #component: 
@@ -589,7 +612,7 @@
             )
            #(#DataSetSpec
               #name: 'Process Table'
-              #layout: #(#LayoutFrame 0 0.0 32 0.0 0 1.0 0 1.0)
+              #layout: #(#LayoutFrame 0 0.0 32 0.0 0 1.0 -23 1)
               #model: #selectedProcesses
               #menu: #tableMenu
               #hasHorizontalScrollBar: true
@@ -603,6 +626,74 @@
               #verticalSpacing: 0
               #postBuildCallback: #postBuildProcessTable:
             )
+           #(#ArrowButtonSpec
+              #name: 'ArrowButton1'
+              #layout: #(#LayoutFrame -22 1 -22 1 0 1 0 1)
+              #model: #increaseupdateListDelayTime
+              #enableChannel: #enableIncreaseListDelayTime
+              #isTriggerOnDown: true
+              #actionValue: ''
+              #direction: #right
+            )
+           #(#InputFieldSpec
+              #name: 'EntryField1'
+              #layout: #(#LayoutFrame -66 1 -22 1 -22 1 0 1)
+              #model: #updateListDelayTime
+              #acceptOnReturn: true
+              #acceptOnTab: true
+              #acceptOnLostFocus: true
+              #acceptOnPointerLeave: false
+            )
+           #(#ArrowButtonSpec
+              #name: 'ArrowButton2'
+              #layout: #(#LayoutFrame -88 1 -22 1 -66 1 0 1)
+              #model: #decreaseupdateListDelayTime
+              #enableChannel: #enableDecreaseListDelayTime
+              #isTriggerOnDown: true
+              #actionValue: ''
+              #direction: #left
+            )
+           #(#LabelSpec
+              #label: 'Update List Delay:'
+              #name: 'Label1'
+              #layout: #(#LayoutFrame 559 0 -20 1 698 0 0 1)
+              #translateLabel: true
+              #adjust: #right
+            )
+           #(#LabelSpec
+              #label: 'Update Contents Delay:'
+              #name: 'Label2'
+              #layout: #(#LayoutFrame 288 0 -20 1 446 0 0 1)
+              #translateLabel: true
+              #adjust: #right
+            )
+           #(#ArrowButtonSpec
+              #name: 'ArrowButton3'
+              #layout: #(#LayoutFrame -273 1 -22 1 -251 1 0 1)
+              #model: #increaseupdateContentsDelayTime
+              #enableChannel: #enableIncreaseContentsDelayTime
+              #isTriggerOnDown: true
+              #actionValue: ''
+              #direction: #right
+            )
+           #(#InputFieldSpec
+              #name: 'EntryField2'
+              #layout: #(#LayoutFrame -317 1 -22 1 -273 1 0 1)
+              #model: #updateContentsDelayTime
+              #acceptOnReturn: true
+              #acceptOnTab: true
+              #acceptOnLostFocus: true
+              #acceptOnPointerLeave: false
+            )
+           #(#ArrowButtonSpec
+              #name: 'ArrowButton4'
+              #layout: #(#LayoutFrame -339 1 -22 1 -317 1 0 1)
+              #model: #decreaseupdateContentsDelayTime
+              #enableChannel: #enableDecreaseContentsDelayTime
+              #isTriggerOnDown: true
+              #actionValue: ''
+              #direction: #left
+            )
            )
          
         )
@@ -1160,12 +1251,66 @@
 
 !ProcessMonitorV2 methodsFor:'actions'!
 
+changeSelectionTo:aSelection
+
+    aSelection notNil ifTrue:[
+        | newSelection |
+        newSelection := OrderedCollection new.
+        aSelection do:[:processItem |
+            | index | 
+            index := processList findFirst:[:anItem | (anItem processInstance == processItem processInstance)].
+            index ~~ 0 ifTrue:[
+                newSelection add:(processList at:index).
+            ].
+        ].            
+        self selectedProcesses value:newSelection 
+    ].
+!
+
+changeSelectionToProcess:aProcessList
+
+    aProcessList notNil ifTrue:[
+        | newSelection |
+        newSelection := OrderedCollection new.
+        aProcessList do:[:aProcess |
+            | index | 
+            index := processList findFirst:[:anItem | (anItem processInstance == aProcess)].
+            index ~~ 0 ifTrue:[
+                newSelection add:(processList at:index).
+            ].
+        ].            
+        self selectedProcesses value:newSelection 
+    ].
+!
+
+decreaseupdateContentsDelayTime
+
+    self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime - 0.1).
+    self evaluateEnableInDecreaseButtons.
+!
+
+decreaseupdateListDelayTime
+
+    self updateListDelayTime value:(self scaledUpdateListDelayTime - 0.1).
+    self evaluateEnableInDecreaseButtons.
+!
+
 doubleClickedAt:anItemIndex
     "open a debugger on the selected process"
 
     self debugProcess
 !
 
+evaluateEnableInDecreaseButtons
+
+    | contDelaySmallerListDelay |
+
+    contDelaySmallerListDelay := (self scaledUpdateContentsDelayTime <= (self scaledUpdateListDelayTime)).
+    self enableDecreaseContentsDelayTime value:((self scaledUpdateContentsDelayTime <= 0.1) not).
+    self enableDecreaseListDelayTime value:contDelaySmallerListDelay.
+    self enableIncreaseContentsDelayTime value:contDelaySmallerListDelay.
+!
+
 getProcessList
     "select processes to display.
      Subclasses may redefine this"
@@ -1180,6 +1325,18 @@
     ^ coll
 !
 
+increaseupdateContentsDelayTime
+
+    self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime + 0.1).
+    self evaluateEnableInDecreaseButtons.
+!
+
+increaseupdateListDelayTime
+
+    self updateListDelayTime value:(self scaledUpdateListDelayTime + 0.1).
+    self evaluateEnableInDecreaseButtons.
+!
+
 selectedProcessesDo:aBlock
     | sel|
 
@@ -1211,6 +1368,38 @@
     ^ currentSortOrder
 !
 
+enableDecreaseContentsDelayTime
+
+    enableDecreaseContentsDelayTime isNil ifTrue:[
+        enableDecreaseContentsDelayTime := true asValue.
+    ].
+    ^ enableDecreaseContentsDelayTime.
+!
+
+enableDecreaseListDelayTime
+
+    enableDecreaseListDelayTime isNil ifTrue:[
+        enableDecreaseListDelayTime := true asValue.
+    ].
+    ^ enableDecreaseListDelayTime.
+!
+
+enableIncreaseContentsDelayTime
+
+    enableIncreaseContentsDelayTime isNil ifTrue:[
+        enableIncreaseContentsDelayTime := true asValue.
+    ].
+    ^ enableIncreaseContentsDelayTime.
+!
+
+enableIncreaseListDelayTime
+
+    enableIncreaseListDelayTime isNil ifTrue:[
+        enableIncreaseListDelayTime := true asValue.
+    ].
+    ^ enableIncreaseListDelayTime.
+!
+
 hasSelection
 
     hasSelection isNil ifTrue:[
@@ -1227,6 +1416,16 @@
     ^ processList.
 !
 
+scaledUpdateContentsDelayTime
+
+    ^ self updateContentsDelayTime value asFloat asFixedPoint:1.
+!
+
+scaledUpdateListDelayTime
+
+    ^ self updateListDelayTime value asFloat asFixedPoint:1.
+!
+
 selectedProcesses
 
     selectedProcesses isNil ifTrue:[
@@ -1259,7 +1458,7 @@
     sortBlock isNil ifTrue:[
         sortBlock := [:a :b |
             a idVal < b idVal
-        ]
+        ].
     ].
     ^ sortBlock
 !
@@ -1270,6 +1469,24 @@
         tableColumns := self class tableColumns asValue.
     ].
     ^ tableColumns.
+!
+
+updateContentsDelayTime
+
+    updateContentsDelayTime isNil ifTrue:[
+        updateContentsDelayTime := updateDelay asValue.
+        updateContentsDelayTime onChangeSend:#evaluateEnableInDecreaseButtons to:self.
+    ].
+    ^ updateContentsDelayTime.
+!
+
+updateListDelayTime
+
+    updateListDelayTime isNil ifTrue:[
+        updateListDelayTime := listUpdateDelay asValue.
+        updateListDelayTime onChangeSend:#evaluateEnableInDecreaseButtons to:self.
+    ].
+    ^ updateListDelayTime.
 ! !
 
 !ProcessMonitorV2 methodsFor:'aspects column'!
@@ -1402,9 +1619,16 @@
 
 viewedColumnsChanged
 
-    | columns buffer locCurrentSortOrder currentSortOrderColumn currentSortOrderReverse selection|
-
-    selection := self selectedProcesses value.
+    | columns buffer locCurrentSortOrder currentSortOrderColumn currentSortOrderReverse oldSelection sel|
+
+    sel := self selectedProcesses value.
+    sel notNil ifTrue:[
+        oldSelection := OrderedCollection new.
+        sel do:[:proItem|
+            oldSelection add:(proItem processInstance)    
+        ].
+    ].
+"/    Transcript showCR:'oldSelection on catch in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
     columns := OrderedCollection new.
     self class tableColumns do:[:el|
         columns add:(DataSetColumnSpec new fromLiteralArrayEncoding:el).
@@ -1460,11 +1684,12 @@
             ]
         ]
     ].
+    self tableColumns value:columns.
+    self updateTable:nil.
     updateSema critical:[
-        self tableColumns value:columns.
-        self selectedProcesses value:selection.
+"/        Transcript showCR:'oldSelection on set in viewedColumnsChanged', (oldSelection isNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
+        self changeSelectionToProcess:oldSelection.
     ].
-    self updateList.
 ! !
 
 !ProcessMonitorV2 methodsFor:'event handling'!
@@ -1544,6 +1769,7 @@
     self updateList.
     self startUpdateProcess.
     self selectionChanged.
+    self sortProcessListBy:#idVal.
     self windowGroup addPreEventHook:self.
 ! !
 
@@ -1861,6 +2087,7 @@
                sel).
         ]
     ].
+    ^ 'unknown'
 ! !
 
 !ProcessMonitorV2 methodsFor:'sorting'!
@@ -1886,7 +2113,6 @@
             currentSortOrder at:#column put:aSymbol.
         ]
     ].
-    self viewedColumnsChanged.
     (currentSortOrder at:#reverse) ifTrue:[
         cmpOp := #'>'
     ] ifFalse:[
@@ -1897,24 +2123,257 @@
 
             entry1 := (a perform:aSymbol).
             entry2 := (b perform:aSymbol).
-            entry1 perform:cmpOp with:entry2 
+            entry1 = entry2 ifTrue:[
+                a idVal < b idVal
+            ] ifFalse:[
+                entry1 perform:cmpOp with:entry2 
+            ]
         ].
-    updateSema critical:[
-        | oldList |
-        oldList := self processList copy.
-        self processList contents:(oldList sort:sortBlock)
-    ].
+   self viewedColumnsChanged.
 ! !
 
 !ProcessMonitorV2 methodsFor:'update process'!
 
-createItemWith:aProcess
-
-    | running con processItem|
-
-    processItem := ProcessItem new.
-
-    processItem processInstance:aProcess.
+redrawChangedItems:oldItem newItem:newItem on:index
+
+    | colIdx |
+    colIdx := 1.
+
+    oldItem processInstance:newItem processInstance.
+    "/ ID
+    oldItem processId ~= newItem processId ifTrue:[
+        oldItem processId:newItem processId.
+        processTable invalidateRowAt:index colAt:colIdx.
+    ].
+    "/ GROUP
+    self showGroup value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processGroup ~= newItem processGroup ifTrue:[
+            oldItem processGroup:newItem processGroup.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ NAME
+    colIdx := colIdx + 1.
+    oldItem processName ~= newItem processName ifTrue:[
+        oldItem processName:newItem processName.
+        processTable invalidateRowAt:index colAt:colIdx.
+    ].
+    "/ STATE
+    self showState value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processState ~= newItem processState ifTrue:[
+            oldItem processState:newItem processState.
+"/            self halt.
+            (processTable columnAt:colIdx).
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ PRIO
+    self showPrio value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processPrio ~= newItem processPrio ifTrue:[
+            oldItem processPrio:newItem processPrio.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ USED STACK
+    self showUsedStack value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processUsedStack ~= newItem processUsedStack ifTrue:[
+            oldItem processUsedStack:newItem processUsedStack.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ TOTAL STACK
+    self showTotalStack value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processTotalStack ~= newItem processTotalStack ifTrue:[
+            oldItem processTotalStack:newItem processTotalStack.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ CURRENT SEGMENT
+    self showCurrentSegment value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processCurrentSegment ~= newItem processCurrentSegment ifTrue:[
+            oldItem processCurrentSegment:newItem processCurrentSegment.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ Switch
+    self showSwitch value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processSwitch ~= newItem processSwitch ifTrue:[
+            oldItem processSwitch:newItem processSwitch.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+    "/ WHERE
+    self showWhere value ifTrue:[
+        colIdx := colIdx + 1.
+        oldItem processWhere ~= newItem processWhere ifTrue:[
+            oldItem processWhere:newItem processWhere.
+            processTable invalidateRowAt:index colAt:colIdx.
+        ].
+    ].
+!
+
+startUpdateProcess
+    updateBlock notNil ifTrue:[
+        Processor addTimedBlock:updateBlock afterSeconds:self scaledUpdateContentsDelayTime.
+        Processor addTimedBlock:listUpdateBlock afterSeconds:self scaledUpdateListDelayTime.
+    ] ifFalse:[
+        updateProcess := [
+            [
+                |id cnt myDelay|
+
+                myDelay := Delay forSeconds:self scaledUpdateContentsDelayTime.
+
+                "
+                 every updateDelay (0.5), we look which process runs;
+                 every half second, the status is updated.
+                 every listUpdateDelay (5s), the list of processes is
+                 built up again
+                "
+                [true] whileTrue:[
+                    ((self scaledUpdateListDelayTime // self scaledUpdateContentsDelayTime) max:2) - 1 timesRepeat:[
+                        myDelay wait.
+                        self updateStatus:nil.
+                    ].
+                    myDelay wait.
+                    self updateList.
+                ]
+            ] valueOnUnwindDo:[
+                updateProcess := nil
+            ]
+        ]  forkAt:(Processor userSchedulingPriority + 1).
+        updateProcess name:'monitor [' , 
+                           Processor activeProcess id printString ,
+                           '] update'.
+        "
+         raise my own priority
+        "
+        Processor activeProcess priority:(Processor userSchedulingPriority + 2)
+    ].
+!
+
+updateList
+
+    |newList|
+
+    processTable shown ifTrue:[
+        newList := self getProcessList.
+        self updateStatus:newList
+    ].
+    updateBlock notNil ifTrue:[
+        Processor removeTimedBlock:listUpdateBlock.
+        Processor addTimedBlock:listUpdateBlock afterSeconds:self scaledUpdateListDelayTime.
+    ].
+!
+
+updateStatus:newProcessList
+
+    |startTime endTime deltaT|
+
+
+    startTime := AbsoluteTime now.
+    self updateTable:newProcessList.
+
+    endTime := AbsoluteTime now.
+    deltaT := (endTime millisecondDeltaFrom:startTime) / 1000.0.
+"/    Transcript show:deltaT; show:' ' ; showCR:(self scaledUpdateContentsDelayTime / 10.0).
+    deltaT > (self scaledUpdateContentsDelayTime / 5) ifTrue:[
+        "/ the update took longer than 20% - make delay longer, to reduce cpu load.
+        self updateContentsDelayTime value:(self scaledUpdateContentsDelayTime * 2).
+        "/ Transcript show:'+++ '; showCR:self scaledUpdateContentsDelayTime.
+    ] ifFalse:[
+        self scaledUpdateContentsDelayTime > 0.5 ifTrue:[
+            deltaT < (self scaledUpdateContentsDelayTime / 20) ifTrue:[
+                "/ the update took less than 5% - make delay smaller for better animation.
+                self updateContentsDelayTime value:((self scaledUpdateContentsDelayTime / 2) max:0.5).
+                "/ Transcript show:'--- ';showCR:self scaledUpdateContentsDelayTime.
+            ].
+        ].
+    ].
+    updateBlock notNil ifTrue:[
+        Processor removeTimedBlock:updateBlock.
+        Processor addTimedBlock:updateBlock afterSeconds:self scaledUpdateContentsDelayTime.
+    ]
+!
+
+updateTable:newProcessList
+
+    | oldSelection newList locNewProcs sel|
+
+
+    processTable shown ifTrue:[
+"/        Transcript showCR:('update the table', AbsoluteTime now printString, 'with new list:', newProcessList notNil asString).
+        updateSema critical:[
+            sel := self selectedProcesses value.
+            sel notNil ifTrue:[
+                oldSelection := OrderedCollection new.
+                sel do:[:proItem|
+                    oldSelection add:(proItem processInstance)    
+                ].
+            ].
+"/            Transcript showCR:'oldSelection on catch in updateTable: ', (oldSelection isEmptyOrNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
+            newProcessList isNil ifTrue:[
+                newList := OrderedCollection new.
+                processList do:[:oldItem |
+                    | newItem |
+                    (self showDead value not and:[oldItem processInstance isDead]) ifFalse:[
+                        newItem := oldItem copy.
+                        self validateItem:newItem.
+                        newList add:newItem.
+                    ]
+                ].
+            ]ifFalse:[
+                "/ remove dead processes if not shown
+                self showDead value ifTrue:[
+                    locNewProcs := newProcessList.
+                ] ifFalse:[
+                    locNewProcs := OrderedCollection new.
+                    newProcessList do:[:proc |
+                        proc isDead not ifTrue:[
+                            locNewProcs add:proc
+                        ]
+                    ]
+                ].
+                newList := OrderedCollection new.
+                locNewProcs do:[:process|
+                    | processItem |
+                    processItem := ProcessItem new.
+                    self validateItem:processItem with:process.
+                    newList add:processItem.
+                ].
+            ].
+            newList sort:self sortBlock.
+            newList doWithIndex:[:newItem :index|
+                | oldItem |
+                oldItem := (processList at:index ifAbsent:nil).
+                oldItem isNil ifTrue:[
+                    processList add:newItem beforeIndex:(index)
+                ] ifFalse:[
+                    self redrawChangedItems:oldItem newItem:newItem on:index
+                ]
+            ].
+"/            Transcript showCR:'oldSelection on set in updateTable: ', (oldSelection isEmptyOrNil ifTrue:['nil'] ifFalse:[oldSelection first printString]).
+            self changeSelectionToProcess:oldSelection.
+        ]
+    ].
+!
+
+updateView
+    self updateList.
+    self updateStatus:nil
+!
+
+validateItem:processItem 
+
+    | running con aProcess|
+
+    aProcess := processItem processInstance.
 
     processItem processId:aProcess id.
     processItem idVal:aProcess id ? -1.
@@ -1947,159 +2406,12 @@
     processItem processSwitch:(aProcess numberOfStackBoundaryHits).
 
     processItem processWhere:(self getWhereStringFor:con running:running).
-
-    ^ processItem
 !
 
-startUpdateProcess
-    updateBlock notNil ifTrue:[
-        Processor addTimedBlock:updateBlock afterSeconds:updateDelay.
-        Processor addTimedBlock:listUpdateBlock afterSeconds:listUpdateDelay.
-    ] ifFalse:[
-        updateProcess := [
-            [
-                |id cnt myDelay|
-
-                myDelay := Delay forSeconds:updateDelay.
-
-                "
-                 every updateDelay (0.5), we look which process runs;
-                 every half second, the status is updated.
-                 every listUpdateDelay (5s), the list of processes is
-                 built up again
-                "
-                [true] whileTrue:[
-                    ((listUpdateDelay // updateDelay) max:2) - 1 timesRepeat:[
-                        myDelay wait.
-                        self updateStatus:nil.
-                    ].
-                    myDelay wait.
-                    self updateList.
-                ]
-            ] valueOnUnwindDo:[
-                updateProcess := nil
-            ]
-        ]  forkAt:(Processor userSchedulingPriority + 1).
-        updateProcess name:'monitor [' , 
-                           Processor activeProcess id printString ,
-                           '] update'.
-        "
-         raise my own priority
-        "
-        Processor activeProcess priority:(Processor userSchedulingPriority + 2)
-    ].
-!
-
-updateList
-
-    |newList|
-
-    processTable shown ifTrue:[
-        newList := self getProcessList.
-
-        "sort by id - take care of nil ids of dead processes"
-        newList sort:[:p1 :p2 |
-                         |id1 id2|
-
-                         (p1 isNil or:[(id1 := p1 id) isNil])
-                             ifTrue:[true]
-                             ifFalse:[
-                                 (p2 isNil or:[(id2 := p2 id) isNil])
-                                     ifTrue:[false]
-                                     ifFalse:[id1 < id2]
-                         ]
-                     ].
-        newList ~= processes ifTrue:[
-            self updateStatus:newList
-        ].
-    ].
-    updateBlock notNil ifTrue:[
-        Processor removeTimedBlock:listUpdateBlock.
-        Processor addTimedBlock:listUpdateBlock afterSeconds:listUpdateDelay
-    ].
-!
-
-updateStatus:newProcessList
-
-    |startTime oldSelection newSelection newList dIndex index aProcess processItem endTime deltaT|
-
-    startTime := AbsoluteTime now.
-
-    processTable shown ifTrue:[
-        newProcessList notNil ifTrue:[
-            processes := WeakArray withAll:newProcessList.
-            ((processes findFirst:[:pro1|  pro1 id == 0]) ~= 0) ifTrue:[
-                Transcript showCR:'have'.
-            ].
-        ].
-        processes notNil ifTrue:[
-            newList := OrderedCollection new.
-
-            dIndex := 1.
-            index := 1.
-
-            "/ use while-loop;
-            "/ processList may change size ....
-            
-            [index <= processes size] whileTrue:[
-                aProcess := processes at:index.
-                index := index + 1.
-                (aProcess notNil 
-                and:[aProcess ~~ 0]) ifTrue:[
-                    ((aProcess id) notNil or:[self showDead value]) ifTrue:[
-                        processItem := self createItemWith:aProcess.
-                        (((newList select:[:pro2| (pro2 processInstance == processItem processInstance)]) size) > 0) ifTrue:[
-                            Transcript showCR:'process ', processItem processInstance name asString, ' already in list at ', index asString.
-                        ].
-                        newList add:processItem.
-                        processes at:dIndex put:aProcess.
-                    ]
-                ].
-                dIndex := dIndex + 1
-            ]
-        ].
-        updateSema critical:[
-            oldSelection := self selectedProcesses value.
-            newList sort:self sortBlock.
-            processList contents:(newList asList).
-            oldSelection notNil ifTrue:[
-                newSelection := OrderedCollection new.
-                oldSelection do:[:processItem |
-                    index := newList findFirst:[:anItem | (anItem processInstance == processItem processInstance)].
-                    index ~~ 0 ifTrue:[
-                        newSelection add:(newList at:index).
-                    ].
-                ]            
-            ].
-            self selectedProcesses value:newSelection.
-        ]
-    ].
-    endTime := AbsoluteTime now.
-    deltaT := (endTime millisecondDeltaFrom:startTime) / 1000.0.
-"/    Transcript show:deltaT; show:' ' ; showCR:(updateDelay / 10.0).
-    deltaT > (updateDelay / 5) ifTrue:[
-        "/ the update took longer than 20% - make delay longer, to reduce cpu load.
-        updateDelay := updateDelay * 2.
-        "/ Transcript show:'+++ '; showCR:updateDelay.
-    ] ifFalse:[
-        updateDelay > 0.5 ifTrue:[
-            deltaT < (updateDelay / 20) ifTrue:[
-                "/ the update took less than 5% - make delay smaller for better animation.
-                updateDelay := (updateDelay / 2) max:0.5.
-                "/ Transcript show:'--- ';showCR:updateDelay.
-            ].
-        ].
-    ].
-
-    updateBlock notNil ifTrue:[
-        Processor removeTimedBlock:updateBlock.
-        Processor addTimedBlock:updateBlock afterSeconds:updateDelay
-    ]
-!
-
-updateView
-    self updateList.
-    self updateStatus:nil
+validateItem:processItem with:aProcess
+
+    processItem processInstance:aProcess.
+    self validateItem:processItem
 ! !
 
 !ProcessMonitorV2::ProcessItem methodsFor:'accessing'!
@@ -2272,8 +2584,20 @@
     processWhere := something.
 ! !
 
+!ProcessMonitorV2::ProcessItem methodsFor:'printing'!
+
+displayString
+
+    ^ self processName, '[', self processId asString, ']'
+!
+
+printString
+
+    ^ self processName, '[', self processId asString, ']'
+! !
+
 !ProcessMonitorV2 class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libtool/ProcessMonitorV2.st,v 1.2 2003-01-23 12:22:29 penk Exp $'
+    ^ '$Header: /cvs/stx/stx/libtool/ProcessMonitorV2.st,v 1.3 2003-01-28 11:16:46 penk Exp $'
 ! !