[squeak-dev] The Trunk: Morphic-ul.1152.mcz
commits at source.squeak.org
commits at source.squeak.org
Mon May 30 23:58:20 UTC 2016
Levente Uzonyi uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ul.1152.mcz
==================== Summary ====================
Name: Morphic-ul.1152
Author: ul
Time: 31 May 2016, 1:32:25.341018 am
UUID: a2bb9c46-93c3-4586-84e3-7dff9fec4bd0
Ancestors: Morphic-ul.1151
Make MorphicAlarmQueue not be a subclass of Heap. Use encapsulation instead. Part #2.
=============== Diff against Morphic-ul.1151 ===============
Item was changed:
+ Object subclass: #MorphicAlarmQueue
- Heap subclass: #MorphicAlarmQueue
instanceVariableNames: 'mutex sequenceNumber heap'
classVariableNames: ''
poolDictionaries: ''
category: 'Morphic-Events'!
!MorphicAlarmQueue commentStamp: 'jcg 1/9/2010 13:34' prior: 0!
MorphicAlarmQueue is a specialized Heap. The main change is to stamp each added MorphicAlarm with a sequence number to ensure that alarms scheduled for the same time are executed in the order that they were added.!
Item was changed:
----- Method: MorphicAlarmQueue>>add: (in category 'adding') -----
add: aMorphicAlarm
+ aMorphicAlarm sequenceNumber: self nextSequenceNumber.
+ ^heap add: aMorphicAlarm!
- heap ifNotNil: [
- aMorphicAlarm sequenceNumber: self nextSequenceNumber.
- ^heap add: aMorphicAlarm ].
- (sequenceNumber := sequenceNumber + 1) = 16r3FFFFFFF ifTrue: [
- "Sequence number overflow... reassign sequence numbers starting at 0."
- | alarmList |
- alarmList := self asArray sort: [:msg1 :msg2 |
- msg1 sequenceNumber < msg2 sequenceNumber
- ].
- alarmList withIndexDo: [:msg :ind | msg sequenceNumber: ind-1].
- "The #bitAnd: for the unlikely event that we have > 16r3FFFFFF messages in the queue."
- sequenceNumber := alarmList last sequenceNumber + 1 bitAnd: 16r3FFFFFFF.
- ].
- aMorphicAlarm sequenceNumber: sequenceNumber.
- super add: aMorphicAlarm.
-
- "If we doubt our sanity..."
- false ifTrue: [
- self isValidHeap ifFalse: [self error: 'not a valid heap!!!!!!'].
- ].
- ^aMorphicAlarm!
Item was added:
+ ----- Method: MorphicAlarmQueue>>alarmsDoSafely: (in category 'enumeration') -----
+ alarmsDoSafely: aBlock
+
+ heap asArray do: aBlock!
Item was changed:
----- Method: MorphicAlarmQueue>>detect:ifNone: (in category 'migration') -----
detect: aBlock ifNone: noneBlock
- heap ifNil: [ ^super detect: aBlock ifNone: noneBlock ].
^heap detect: aBlock ifNone: noneBlock!
Item was changed:
----- Method: MorphicAlarmQueue>>do: (in category 'migration') -----
do: aBlock
- heap ifNil: [ ^super do: aBlock ].
^heap do: aBlock!
Item was changed:
----- Method: MorphicAlarmQueue>>first (in category 'migration') -----
first
- heap ifNil: [ ^super first ].
^heap first!
Item was added:
+ ----- Method: MorphicAlarmQueue>>incrementScheduledTimesBy: (in category 'accessing') -----
+ incrementScheduledTimesBy: anInteger
+
+ heap do: [ :each | each scheduledTime: each scheduledTime + anInteger ]!
Item was changed:
----- Method: MorphicAlarmQueue>>initialize (in category 'initialize') -----
initialize
super initialize.
+ mutex := Mutex new.
sequenceNumber := 0.
heap := Heap sortBlock: [ :alarmA :alarmB |
alarmA scheduledTime = alarmB scheduledTime
ifFalse: [ alarmA scheduledTime < alarmB scheduledTime ]
ifTrue: [
alarmA sequenceNumber = alarmB sequenceNumber
ifFalse: [ alarmA sequenceNumber < alarmB sequenceNumber ]
ifTrue: [ self error: 'These alarms run at the same time' ] ] ]!
Item was changed:
----- Method: MorphicAlarmQueue>>isEmpty (in category 'migration') -----
isEmpty
- heap ifNil: [ ^super isEmpty ].
^heap isEmpty!
Item was removed:
- ----- Method: MorphicAlarmQueue>>isValidHeap (in category 'private') -----
- isValidHeap
- "Verify the correctness of the heap"
- 2 to: tally do:[:i|
- (self sorts: (array at: i // 2) before: (array at: i)) ifFalse:[^false].
- ].
- ^true!
Item was removed:
- ----- Method: MorphicAlarmQueue>>migrate (in category 'migration') -----
- migrate
-
- heap ifNotNil: [ ^self ].
- heap := Heap withAll: self asArray sortBlock: [ :alarmA :alarmB |
- alarmA scheduledTime = alarmB scheduledTime
- ifFalse: [ alarmA scheduledTime < alarmB scheduledTime ]
- ifTrue: [
- alarmA sequenceNumber = alarmB sequenceNumber
- ifFalse: [ alarmA sequenceNumber < alarmB sequenceNumber ]
- ifTrue: [ self error: 'These alarms run at the same time' ] ] ]!
Item was changed:
----- Method: MorphicAlarmQueue>>mutex (in category 'accessing') -----
mutex
+
+ ^mutex!
- ^mutex ifNil: [mutex := Mutex new]!
Item was changed:
----- Method: MorphicAlarmQueue>>nextSequenceNumber (in category 'private') -----
nextSequenceNumber
(sequenceNumber := sequenceNumber + 1) = 16r3FFFFFFF ifTrue: [
"Sequence number overflow... reassign sequence numbers starting at 1."
+ heap fullySort.
+ 1 to: heap size do: [ :index |
+ (heap at: index) sequenceNumber: index ].
+ sequenceNumber := heap size + 1 ].
- | alarmList |
- alarmList := heap fullySort asArray.
- alarmList withIndexDo: [ :alarm :index |
- alarm sequenceNumber: index ].
- sequenceNumber := alarmList size + 1 ].
^sequenceNumber!
Item was changed:
+ ----- Method: MorphicAlarmQueue>>postCopy (in category 'copying') -----
- ----- Method: MorphicAlarmQueue>>postCopy (in category 'as yet unclassified') -----
postCopy
super postCopy.
heap := heap copy!
Item was changed:
----- Method: MorphicAlarmQueue>>remove: (in category 'migration') -----
remove: anObject
- heap ifNil: [ ^super remove: anObject ].
^heap remove: anObject!
Item was added:
+ ----- Method: MorphicAlarmQueue>>removeAlarmWithReceiver:selector: (in category 'removing') -----
+ removeAlarmWithReceiver: receiver selector: selector
+
+ heap
+ detect: [ :each | each receiver == receiver and: [ each selector == selector ] ]
+ ifFound: [ :found | heap remove: found ]
+ ifNone: [ ]!
Item was added:
+ ----- Method: MorphicAlarmQueue>>removeAllAlarmsBefore: (in category 'removing') -----
+ removeAllAlarmsBefore: nowTime
+
+ ^Array new: 10 streamContents: [ :stream |
+ [ heap notEmpty and: [ heap first scheduledTime < nowTime ] ]
+ whileTrue: [ stream nextPut: heap removeFirst ] ]!
Item was changed:
----- Method: MorphicAlarmQueue>>removeFirst (in category 'migration') -----
removeFirst
- heap ifNil: [ ^super removeFirst ].
^heap removeFirst!
Item was removed:
- ----- Method: MorphicAlarmQueue>>sorts:before: (in category 'comparing') -----
- sorts: alarmA before: alarmB
- alarmA scheduledTime = alarmB scheduledTime
- ifFalse:[^alarmA scheduledTime < alarmB scheduledTime].
- alarmA sequenceNumber = alarmB sequenceNumber
- ifFalse:[^alarmA sequenceNumber < alarmB sequenceNumber].
- ^self error: 'These alarms run at the same time'!
Item was changed:
----- Method: WorldState>>adjustAlarmTimes: (in category 'alarms') -----
adjustAlarmTimes: nowTime
"Adjust the alarm times after some clock weirdness (such as roll-over, image-startup etc)"
+
| deltaTime |
+ (deltaTime := nowTime - lastAlarmTime) = 0 ifTrue: [ ^self ].
+ self lockAlarmsDuring: [ :locked | locked incrementScheduledTimesBy: deltaTime ]!
- deltaTime := nowTime - lastAlarmTime.
- self lockAlarmsDuring: [:locked |
- locked do:[:alarm| alarm scheduledTime: alarm scheduledTime + deltaTime].
- ]!
Item was changed:
----- Method: WorldState>>cleanseStepListForWorld: (in category 'stepping') -----
cleanseStepListForWorld: aWorld
"Remove morphs from the step list that are not in this World. Often were in a flap that has moved on to another world."
+ | deletions |
- | deletions morphToStep |
deletions := nil.
stepList do: [:entry |
+ entry receiver world == aWorld ifFalse: [
+ (deletions ifNil: [ deletions := OrderedCollection new ])
+ addLast: entry ] ].
- morphToStep := entry receiver.
- morphToStep world == aWorld ifFalse:[
- deletions ifNil: [deletions := OrderedCollection new].
- deletions addLast: entry]].
deletions ifNotNil:[
deletions do: [:entry|
self stopStepping: entry receiver]].
self lockAlarmsDuring: [:locked |
+ locked alarmsDoSafely: [ :entry |
+ | morphToStep |
- locked copy do: [:entry |
morphToStep := entry receiver.
+ (morphToStep isMorph and: [morphToStep world == aWorld]) ifFalse: [
+ locked removeAlarmWithReceiver: entry receiver selector: entry selector ] ] ]!
- (morphToStep isMorph and:[morphToStep world == aWorld])
- ifFalse:[self removeAlarm: entry selector for: entry receiver]]
- ].!
Item was changed:
----- Method: WorldState>>removeAlarm:for: (in category 'alarms') -----
removeAlarm: aSelector for: aTarget
"Remove the alarm with the given selector"
self lockAlarmsDuring: [:locked |
+ locked removeAlarmWithReceiver: aTarget selector: aSelector ]!
- | alarm |
- alarm := locked
- detect: [:any | any receiver == aTarget and: [any selector == aSelector]]
- ifNone: [nil].
- alarm ifNotNil: [locked remove: alarm]
- ].
- !
Item was changed:
----- Method: WorldState>>triggerAlarmsBefore: (in category 'alarms') -----
triggerAlarmsBefore: nowTime
"Trigger all pending alarms that are to be executed before nowTime."
| triggered |
lastAlarmTime ifNil:[lastAlarmTime := nowTime].
(nowTime < lastAlarmTime or:[nowTime - lastAlarmTime > 10000])
ifTrue:[self adjustAlarmTimes: nowTime].
+ triggered := self lockAlarmsDuring: [:pending |
+ pending removeAllAlarmsBefore: nowTime ].
- triggered := OrderedCollection new.
- self lockAlarmsDuring: [:pending |
- [pending isEmpty not and: [pending first scheduledTime < nowTime]]
- whileTrue: [triggered add: pending removeFirst]].
triggered do: [:alarm | alarm value: nowTime].
lastAlarmTime := nowTime.!
More information about the Squeak-dev
mailing list
|