pieter@prls.UUCP (Pieter van der Meulen) (07/11/90)
It has been a while since the last goodie posting, and I noticed some discussions on the (limitations of) Smalltalk processes. Here is a goodie which gives you an idea of what you can and should (not) do with Smalltalk processes. You use it to show a message if users get impatient while Smalltalk is busily computing (at fileIn maybe ? :-) Have fun, Pieter. '-----------------------------------cut here----------------------------------'! 'Suppose you are filing in your application, and you want to display a PLEASE WAIT message only if the mouse buttons are pressed, neither <aCursor showWhile: [...]> nor <aForm follow: [....] while: [...]> are what you want. These sources show you how to do this, i.e. conditionally displaying a DisplayObject. The basic and a derivative display methods for DisplayObject are given. Other display methods like the ones in the DisplayObject>displaying protocol can easily be constructed using the basic display primitive. As an example, the <fileIn> method for FileModel is included. The code works for both Smalltalk version 2.3 and (2.4) 2.5. A <fileIn> initiated from a FileList will display a PLEASE WAIT message if the user pressed a key or mouse button. Note that any KEYS pressed will NOT be flushed. Also, try the examples included in the comment of each display method. Copyright (C) 1990, Pieter S. van der Meulen. This program is placed in the public domain. You may use and alter this program freely for non-commercial purposes as long as you leave this message intact. Neither I nor my company will recognize any responsibility for damages arising from use of this program.'! !DisplayObject methodsFor: 'conditional displaying'! displayForSeconds: secInteger if: testBlock while: evalBlock "This is a simple method for conditional display of objects while evaluating evalBlock. The value of evalBlock is returned. The evalBlock is expected to take some time to execute. If the testBlock evaluates to true during this execution, the receiver will be displayed. The duration of this display is determined by secInteger. If the latter is equal to zero, display will continue until evalBlock is finished. In the example below, the evaluation of evalBlock creates a new active process, which causes an abnormal termination of this method, but gives you a good impression how it all works." "' Still browsing. Please wait. ' asDisplayText form reverse displayForSeconds: 2 if: [Sensor anythingPressed] while: [Smalltalk browseAllCallsOn: #at: and: #at:put:]" ^self displayOn: Display at: [Sensor cursorPoint] clippingBox: Display boundingBox rule: Form over mask: nil forSeconds: secInteger if: testBlock while: evalBlock! displayOn: aDisplayMedium at: pointOrBlock clippingBox: aRect rule: ruleInteger mask: aForm forSeconds: secInteger if: testBlock while: evalBlock "This is the basic display primitive for conditional display of objects while evaluating evalBlock. The value of evalBlock is returned. The evalBlock is expected to take some time to execute. If the testBlock evaluates to true during this execution, the receiver will be displayed. The duration of this display is determined by secInteger. If the latter is equal to zero, display will continue until evalBlock is finished. The location for display is determined by pointOrBlock, which may be a Point or a block which evaluates to aPoint. If pointOrBlock would be [Sensor cursorPoint] and testBlock [true], this method will behave like a 1-second-update-<follow:while:> method. If the evaluation of evalBlock creates a new active process, e.g. opening an Inspector, the receiver may not be able to erase itself from aDisplayMedium. To cover ST-versions, 3 termination tricks are used. The process associated with displaying the receiver needs to run at userInterruptPriority, because the system code implemeting the <fileIn> never issues a <Processor yield>. (C) 1990, Pieter S. van der Meulen." "Cursor crossHair showWhile: [' Showing cursor location in top left corner. Hold SHIFT key for 1 second to terminate.' asDisplayText form reverse displayOn: Display at: [Sensor cursorPoint] clippingBox: Display boundingBox rule: Form over mask: nil forSeconds: 2 if: [Sensor anythingPressed] while: [[Sensor leftShiftDown] whileFalse: [(Sensor cursorPoint printString,' ') asDisplayText displayAt: 0@0]]. Sensor flushKeyboard]" | oldP newP seconds showProcess showing value bgForm thisProcess | seconds _ 0. showing _ true. thisProcess _ Processor activeProcess. showProcess _ [ [(Delay forMilliseconds: 1000) wait. (testBlock isNil or: [thisProcess suspendingList isNil]) ifTrue: [showing _ nil] "Unexpected termination" ifFalse: [testBlock value ifTrue: [seconds _ secInteger. (pointOrBlock isKindOf: Point) ifTrue: [oldP _ pointOrBlock] ifFalse: "Trace without flashing" [newP _ pointOrBlock value. (oldP ~= newP and: [bgForm notNil]) ifTrue: [bgForm display. bgForm _ nil]. oldP _ newP]. bgForm isNil ifTrue: [aDisplayMedium = Display ifTrue: [bgForm _ self backgroundAt: oldP + self offset]. self displayOn: aDisplayMedium at: oldP clippingBox: aRect rule: ruleInteger mask: aForm]]. seconds > 0 ifTrue: [seconds _ seconds - 1. seconds = 0 ifTrue: [bgForm display. bgForm _ nil]]]. showing notNil] whileTrue. bgForm notNil ifTrue: [bgForm display]] newProcess. showProcess priority: Processor userInterruptPriority. showProcess resume. value _ evalBlock value. showing _ nil. "Proper termination of the showProcess." [showProcess suspendingList isNil] whileFalse. bgForm notNil ifTrue: [bgForm display]. ^value! ! !InputSensor methodsFor: 'mouse'! anythingPressed "Answer whether anything is being pressed." ^self anyButtonPressed or: [self keyboardPressed or: [self leftShiftDown or: [self ctrlDown]]]! ! !FileModel methodsFor: 'user protocol'! fileInFile "Read the entire file as Smalltalk code. Display a PLEASE WAIT message if the user pressed a key or mouse button. This methods supports both Smalltalk version 2.3 and (2.4) 2.5. To simplify, take out that part which does not relate to your version." | aForm | aForm _ ('Please wait. Still reading ',fileName) asDisplayText form. ^((Form new extent: aForm extent + (8@8)) black copyBits: (0@0 extent: aForm extent) from: aForm at: (4@4) clippingBox: (0@0 extent: aForm extent + (8@8)) rule: Form over mask: Form black) displayOn: Display at: [Sensor cursorPoint] clippingBox: Display boundingBox rule: Form over mask: nil forSeconds: 3 if: [Sensor anythingPressed] while: [('*2.5*' match: Smalltalk version) ifTrue: [(Filename named: fileName) fileIn] ifFalse: [(FileStream oldFileNamed: fileName) fileIn]]! ! '-----------------------------------cut here----------------------------------'! -- --------------------------------------------- P.S. van der Meulen, MS 02 prls!pieter PRLS, Signetics div. of NAPC ----------- 811 E.Arques Avenue, Sunnyvale, CA 94088-3409