[squeak-dev] The Trunk: Morphic-jcg.280.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Jan 9 21:48:29 UTC 2010


Joshua Gargus uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-jcg.280.mcz

==================== Summary ====================

Name: Morphic-jcg.280
Author: jcg
Time: 9 January 2010, 1:36:45 am
UUID: fe5a8f31-e1df-41d0-b266-cd8c15e86f64
Ancestors: Morphic-dtl.279

Following Bert's suggestion in the "Future Sends" thread, use MorphicAlarms instead of forking a Process that immediately waits on a delay before scheduling them with the other deferred messages.

This is Morphic-only behavior (implemented in MorphicProject), since other types of Projects don't have the MorphicAlarm mechanism available to them.

=============== Diff against Morphic-dtl.279 ===============

Item was added:
+ ----- Method: MorphicAlarm>>sequenceNumber (in category 'accessing') -----
+ sequenceNumber
+ 	"Answer the sequence number of the alarm, which is used to preserve ordering for alarms scheduled for the same time."
+ 	^sequenceNumber ifNil: [0]!

Item was added:
+ ----- Method: MorphicProject>>future:send:at:args: (in category 'futures') -----
+ future: receiver send: aSelector at: deltaMSecs args: args
+ 	"Send a message deltaSeconds into the future.  Answers a Promise that will be resolved at some time in the future."
+ 	| pr closure |
+ 	pr := Promise new.
+ 	closure := [pr resolveWith: (receiver perform: aSelector withArguments: args)].
+ 	deltaMSecs = 0
+ 		ifTrue: [self addDeferredUIMessage: closure]
+ 		ifFalse: [
+ 			world 
+ 				addAlarm: #addDeferredUIMessage: 
+ 				withArguments: {closure}
+ 				for: self
+ 				at: (Time millisecondClockValue + deltaMSecs)
+ 		].
+ 	^pr
+ 		!

Item was added:
+ ----- Method: MorphicAlarmQueue>>initialize (in category 'initialize') -----
+ initialize
+ 	super initialize.
+ 	sequenceNumber := 0.!

Item was added:
+ ----- 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 added:
+ ----- Method: MorphicAlarmQueue class>>convertAllAlarms (in category 'class initialization') -----
+ convertAllAlarms
+ 	"Alarms should be kept in a MorphicAlarmQueue, not a Heap."
+ 	WorldState allSubInstancesDo: [:ws | ws convertAlarms]!

Item was added:
+ ----- Method: MorphicProject>>future:do:at:args: (in category 'futures') -----
+ future: receiver do: aSelector at: deltaMSecs args: args
+ 	"Send a message deltaSeconds into the future.  No response is expected."
+ 	| msg |
+ 	msg := MessageSend receiver: receiver selector: aSelector arguments: args.
+ 	deltaMSecs = 0 
+ 		ifTrue: [self addDeferredUIMessage: msg]
+ 		ifFalse: [
+ 			world 
+ 				addAlarm: #addDeferredUIMessage: 
+ 				withArguments: {msg}
+ 				for: self
+ 				at: (Time millisecondClockValue + deltaMSecs)
+ 		]..
+ 	^nil!

Item was added:
+ Heap subclass: #MorphicAlarmQueue
+ 	instanceVariableNames: 'sequenceNumber'
+ 	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 added:
+ ----- Method: MorphicAlarmQueue class>>initialize (in category 'class initialization') -----
+ initialize
+ 	self convertAllAlarms.!

Item was changed:
  ----- Method: WorldState>>convertAlarms (in category 'object fileIn') -----
  convertAlarms
+ 	"We now store the alarms in a MorphicAlarmQueue, rather than a Heap."
+ 	alarms ifNotNil: [
+ 		alarms class == MorphicAlarmQueue ifFalse: [
+ 			| oldAlarms |
+ 			oldAlarms := alarms.
+ 			alarms := MorphicAlarmQueue new.
+ 			oldAlarms do: [:alarm | alarms add: alarm]			
+ 		]
+ 	].!
- 	
- 	alarms ifNotNil: [alarms sortBlock: self alarmSortBlock].	"ensure cleaner block"
- 
- !

Item was changed:
  MessageSend subclass: #MorphicAlarm
+ 	instanceVariableNames: 'scheduledTime sequenceNumber numArgs'
- 	instanceVariableNames: 'scheduledTime numArgs'
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'Morphic-Events'!

Item was added:
+ ----- 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 added:
+ ----- Method: MorphicAlarmQueue>>add: (in category 'adding') -----
+ 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!!!!!!'].
+ 	]!

Item was changed:
  ----- Method: WorldState>>alarms (in category 'alarms') -----
  alarms
  
+ 	^alarms ifNil: [alarms := MorphicAlarmQueue new]!
- 	^alarms ifNil: [alarms := Heap sortBlock: self alarmSortBlock]!

Item was added:
+ ----- Method: MorphicAlarm>>sequenceNumber: (in category 'accessing') -----
+ sequenceNumber: positiveInteger
+ 	"Set the sequence number of the alarm, which is used to preserve ordering for alarms scheduled for the same time."
+ 	sequenceNumber := positiveInteger!




More information about the Squeak-dev mailing list