123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- Smalltalk createPackage: 'Axxord-Axon'!
- Object subclass: #Axon
- instanceVariableNames: 'factory'
- package: 'Axxord-Axon'!
- !Axon commentStamp!
- I represent a pub-sub based on a key (called 'aspect').
- I manage aspect-block subscriptions (called 'interests') as well as run blocks of dirtied interests.
- The interest objects are responsible of decision if the change of an aspect is relevant for them.
- Interest object must be subclasses of `AxonInterest`.
- My subclasses must provide implementation for:
- - add:
- - do:
- - clean!
- !Axon methodsFor: 'accessing'!
- addInterest: anInterest
- self
- add: (anInterest flag; yourself);
- dirty: true
- ! !
- !Axon methodsFor: 'change-update'!
- changed: anAspect
- | needsToRun |
- needsToRun := false.
- self do: [ :each |
- (each accepts: anAspect) ifTrue: [
- each flag.
- needsToRun := true ]].
- self dirty: needsToRun
- !
- changedAll
- | needsToRun |
- needsToRun := false.
- self do: [ :each |
- each flag.
- needsToRun := true ].
- self dirty: needsToRun
- ! !
- !Axon methodsFor: 'primitive ops'!
- add: anInterest
- self subclassResponsibility
- !
- clean
- self subclassResponsibility
- !
- do: aBlock
- self subclassResponsibility
- ! !
- !Axon methodsFor: 'private'!
- dirty: aBoolean
- aBoolean ifTrue: [[ self run ] fork]
- !
- run
- [
- | needsClean |
- needsClean := false.
- self do: [ :each |
- each isFlagged ifTrue: [ each run ].
- each isClosed ifTrue: [ needsClean := true ]
- ].
- needsClean ifTrue: [ self clean ]
- ] on: Error do: [ self dirty: true ]
- ! !
- Axon subclass: #SimpleAxon
- instanceVariableNames: 'queue'
- package: 'Axxord-Axon'!
- !SimpleAxon methodsFor: 'initialization'!
- initialize
- super initialize.
- queue := OrderedCollection new
- ! !
- !SimpleAxon methodsFor: 'primitive ops'!
- add: aSubscription
- queue add: aSubscription.
- !
- clean
- queue := queue reject: [ :each | each isClosed ]
- !
- do: aBlock
- queue do: aBlock
- ! !
- Object subclass: #AxonInterest
- instanceVariableNames: 'flagged'
- package: 'Axxord-Axon'!
- !AxonInterest methodsFor: 'accessing'!
- flag
- flagged := true
- ! !
- !AxonInterest methodsFor: 'action'!
- close
- self subclassResponsibility
- !
- enact
- self subclassResponsibility
- !
- run
- [ flagged := false. self enact ]
- on: AxonOff do: [ self close ]
- ! !
- !AxonInterest methodsFor: 'initialization'!
- initialize
- super initialize.
- flagged := false.
- ! !
- !AxonInterest methodsFor: 'testing'!
- accepts: anAspect
- "Should return true if change for anAspect is relevant for this AxonInterest"
- self subclassResponsibility
- !
- isClosed
- self subclassResponsibility
- !
- isFlagged
- ^flagged
- ! !
- AxonInterest subclass: #PluggableInterest
- instanceVariableNames: 'acceptBlock enactBlock'
- package: 'Axxord-Axon'!
- !PluggableInterest methodsFor: 'accessing'!
- accept: aBlock enact: anotherBlock
- acceptBlock := aBlock.
- enactBlock := anotherBlock
- ! !
- !PluggableInterest methodsFor: 'action'!
- close
- acceptBlock := nil.
- enactBlock := nil
- !
- enact
- enactBlock value
- ! !
- !PluggableInterest methodsFor: 'initialization'!
- initialize
- super initialize.
- self close
- ! !
- !PluggableInterest methodsFor: 'testing'!
- accepts: anAspect
- ^ acceptBlock value: anAspect
- !
- isClosed
- ^ acceptBlock isNil
- ! !
- Error subclass: #AxonOff
- instanceVariableNames: ''
- package: 'Axxord-Axon'!
- !AxonOff commentStamp!
- Signal me from the subscription block to unsubscribe it.!
|