138 lines
3.7 KiB
Smalltalk
138 lines
3.7 KiB
Smalltalk
"
|
|
I am an implementation of the memento design pattern.
|
|
|
|
My goal is to remember the state of a PPContext to eventually be able to restore its state later.
|
|
|
|
I should be instantiated using PPContext>>#memorize method.
|
|
|
|
A PPContext can restore its state by providing the memento to PPContext>>#restore:.
|
|
"
|
|
Class {
|
|
#name : 'PPContextMemento',
|
|
#superclass : 'Object',
|
|
#instVars : [
|
|
'stream',
|
|
'position',
|
|
'properties'
|
|
],
|
|
#category : 'PetitParser-Core'
|
|
}
|
|
|
|
{ #category : 'comparing' }
|
|
PPContextMemento >> = anObject [
|
|
|
|
(self == anObject) ifTrue: [ ^ true ].
|
|
(anObject class = PPContextMemento) ifFalse: [ ^ false ].
|
|
|
|
(anObject stream == stream) ifFalse: [ ^ false ].
|
|
(anObject position == position) ifFalse: [ ^ false ].
|
|
|
|
(self propertiesSize == anObject propertiesSize) ifFalse: [ ^ false ].
|
|
|
|
self keysAndValuesDo: [ :key :value |
|
|
(anObject hasProperty: key) ifFalse: [ ^ false ].
|
|
((anObject propertyAt: key) = value) ifFalse: [ ^ false ].
|
|
].
|
|
|
|
^ true.
|
|
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> hasProperty: aKey [
|
|
"Test if the property aKey is present."
|
|
|
|
^ properties notNil and: [ properties includesKey: aKey ]
|
|
]
|
|
|
|
{ #category : 'comparing' }
|
|
PPContextMemento >> hash [
|
|
^ (position hash bitXor: stream hash) bitXor: properties hash.
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> keysAndValuesDo: aBlock [
|
|
properties ifNil: [ ^ self ].
|
|
properties keysAndValuesDo: [ :key :value | aBlock value: key value: value copy ]
|
|
]
|
|
|
|
{ #category : 'accessing' }
|
|
PPContextMemento >> position [
|
|
^ position
|
|
]
|
|
|
|
{ #category : 'accessing' }
|
|
PPContextMemento >> position: anInteger [
|
|
position := anInteger
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> propertiesSize [
|
|
properties ifNil: [ ^ 0 ].
|
|
^ properties size.
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> propertyAt: aKey [
|
|
"Answer the property value associated with aKey."
|
|
|
|
^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ]
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> propertyAt: aKey ifAbsent: aBlock [
|
|
"Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock."
|
|
|
|
properties isNil
|
|
ifTrue: [ ^ aBlock value ]
|
|
ifFalse: [
|
|
(properties includesKey: aKey) ifTrue: [
|
|
^ (properties at: aKey) copy
|
|
].
|
|
^ aBlock value
|
|
]
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> propertyAt: aKey ifAbsentPut: aBlock [
|
|
"Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value."
|
|
|
|
^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> propertyAt: aKey put: anObject [
|
|
"Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject."
|
|
|
|
^ (properties ifNil: [ properties := Dictionary new: 1 ])
|
|
at: aKey put: (anObject copy)
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> removeProperty: aKey [
|
|
"Remove the property with aKey. Answer the property or raise an error if aKey isn't found."
|
|
|
|
^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ]
|
|
]
|
|
|
|
{ #category : 'accessing - properties' }
|
|
PPContextMemento >> removeProperty: aKey ifAbsent: aBlock [
|
|
"Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock."
|
|
|
|
| answer |
|
|
properties isNil ifTrue: [ ^ aBlock value ].
|
|
answer := properties removeKey: aKey ifAbsent: aBlock.
|
|
properties isEmpty ifTrue: [ properties := nil ].
|
|
^ answer
|
|
]
|
|
|
|
{ #category : 'accessing' }
|
|
PPContextMemento >> stream [
|
|
^ stream
|
|
]
|
|
|
|
{ #category : 'accessing' }
|
|
PPContextMemento >> stream: aStream [
|
|
stream := aStream
|
|
]
|