Stéphane your previous question makes me think of a better solutionwith requires only one mandatory class and which makes use of standard event notification (without PreferenceCollector).
I've joined 4 packages : - PrefCore contains PreferenceValue which is now the only mandatory class. 2 packages for testing: - PrefProvider contains PrefProvider class which declares some preferences - PrefUser contains PrefChangeListener (try PrefChangeListener test). 1 package for UI:- PrefTool contains PreferenceCollector and PreferenceDefinition. They are optional.
Code below do not makes use of PreferenceCollector anymore: PrefChangeListener>>initialize super initialize.gradientLook := PrefProvider gradientButtonLook value. "reading of the preference value"
"Using of standard event notification engine"PrefProvider when: #gradientButtonLook send: #gradientButtonLookIsNow: to: self.
PrefProvider when: #gradientButtonLook send: #gradientLook: to: self. Now, the preference system only need PreferenceValue. PreferenceCollector and PreferenceDefinition are optional and can be brought by a preference supporting tool (UI).Previous version implied a dependency from PrefChangeListener to PreferenceCollector which was bad.
PrefChangeListener>>initialize super initialize. gradientLook := PrefProvider gradientButtonLook value.PreferenceCollector whenChanged: #gradientButtonLook inClass: PrefProvider notify: self using: #gradientButtonLookIsNow: . PreferenceCollector whenChanged: #gradientButtonLook inClass: PrefProvider notify: self using: #gradientLook:
alain Stéphane Ducasse a écrit :
> sounds cool.> For me the most important aspect is that preferenceCollector (our > current preference class should be a removable layer on top> of the system that are declaring preference. > > Is is correct that >> PreferenceCollector whenChanged: #gradientButtonLook inClass: > PrefProvider notify: self using: #gradientButtonLookIsNow: .> > means that PrefProvider will receive the message > gradientButtonLookIsNow:
no, but see the code below: ----------- PrefListener>>initialize super initialize.PreferenceCollector whenChanged: #gradientButtonLook inClass: PrefProvider notify: self using: #gradientButtonLookIsNow: .
-----------it means that a PrefListener instance will receive the #gradientButtonLookIsNow: message each time the preference #gradientButtonLook defined in class PrefProvider is changed.
PrefListener and PrefProvider represent can be any class in the system.So, in order to read a preference value an object get it from the provider class by message sending, the provider is a class in a package which defines preferences (no need for PreferenceCollector to get the preference value).
>> This way we can push preference to the tools
yes
> and thety do not have to query the information in the Collector at > run-time
yes,Each package have its own preference set in it represented by a set of methods with pragma. When such a package is loaded, its preferences are automatically stored by PreferenceCollector. When a package is removed, its preferences are automatically removed from PreferenceCollector. PreferenceCollector is only here for supporting tools (cool UI ...) and for change notifications.
> (hence we could remove Preference and have a more OO design).
I guess yes.
bon courage :)>> Sorry not to reply earlier (I was breaking yet another wall in our > "kitchen")
alain
> > Stef > > > On Mar 1, 2009, at 10:05 AM, Alain Plantec wrote: >>> Hi all, >>>> joined Zoo package is a attempt to translate in code what we >> discussed here before about preference refactoring.>>>> The framework is made of 3 classes: PreferenceCollector, >> PreferenceDefinition and PreferenceValue. >> In Zoo there are also 2 classes for testing: PrefProvider and >> PrefChangeListener. >> PrefProvider class declares some preferences and PrefChangeListener >> is here to test preference change notification.>> >> PrefChangeListener>>initialize >> super initialize.>> PreferenceCollector whenChanged: #gradientButtonLook inClass: >> PrefProvider notify: self using: #gradientButtonLookIsNow: . >> PreferenceCollector whenChanged: #gradientButtonLook inClass: >> PrefProvider notify: self using: #gradientLook:>> >> PrefChangeListener class>>test >> "self test" >> PrefChangeListener new inspect.>> PrefProvider gradientButtonLook: PrefProvider gradientButtonLook >> value not. >> PrefProvider gradientButtonLook: PrefProvider gradientButtonLook >> value not. >> PrefProvider gradientButtonLook: PrefProvider gradientButtonLook >> value not.>> >> >> From PreferenceCollector comment: >> -------------------------------------- >> A PreferenceCollector automatically collects all preferences. >> A preference is represented by a PreferenceDefinition.>> All PreferenceDefinition are stored in the preferences instance >> variable.>> >> Instance Variables >> preferences: OrderedCollection of PreferenceDefinition >> >> preferences>> - contains all PreferenceDefinition which are automatically built >> from pragma found in preference getters>> >> >> ADDING A PREFERENCE>> PreferenceCollector makes use of the SystemChangeNotifier in order to >> automate the adding, the removing and the updating of preferences. >> See #PreferenceCollector>>event: to see how preferences update is >> implemented.>>>> Editing a new method with a preference pragma or inserting a >> preference pragma in an existing method are>> the two ways for preference definition adding.>> The only way to remove a preference definition is to remove the >> corresponding method.>> >> Example of a "blackAndWhite" preference.>> Methods below are defined by the preference provider >> APreferencePrivider class. >> Note that the value stored in BlackAndWhite class variable is an >> instance of PreferenceValue.>> In this example, the default value is directly given with the pragma: >> ------------- >> APreferencePrivider class>>blackAndWhite>> <preference: 'Use black and white' type: #Boolean set: >> #blackAndWhite: defaultValue: false description: 'Use black and white'>>> ^ BlackAndWhite>> ifNil: [BlackAndWhite := PreferenceValue value: false location: >> self selector: #blackAndWhite]>> >> APreferencePrivider class>>blackAndWhite: aBoolean >> self blackAndWhite value: aBoolean >> ------------- >>>> If a default value can't be specified in the pragma, another way >> consists in using a selector which >> represents the message to send to the class in order to get the >> default value:>> >> ------------- >> APreferencePrivider class>>standardFont>> <preference: 'The default system font' type: #LogicalFont set: >> #standardFont: default: #defaultStandardFont description: 'The >> default system font'>>> ^ StandardFont>> ifNil: [StandardFont := PreferenceValue value: self >> defaultStandardFont location: self selector: #standardFont]>> >> APreferencePrivider class>>standardFont: aFont >> self standardFont value: aFont >> APreferencePrivider class>>defaultStandardFont >> ^ LogicalFont >> familyName: 'Arial' >> fallbackFamilyNames: nil >> pointSize: 12 >> stretchValue: 5 >> weightValue: 400 >> slantValue: 0 >> ------------- >> >> LISTENING TO A PREFERENCE VALUE CHANGE >> Any object can register itself as a preference value change listener. >> See #PreferenceCollector class>>whenChanged: inClass:notify:using:. >>>> Each time a preference value is changed, #preference: >> inClass:changedWith: is sent to the PreferenceCollector class.>>>> Example of code a listener can implement in order to be notified each >> time a gradientButtonLook preference defined by a PrefProvider class >> is changed. >> In this example, the listener ask to be notified by a send of >> #gradientButtonLookIsNow: message. >> The argument given to gradientButtonLookIsNow: is the new preference >> value.>> ------------- >> ....>> PreferenceCollector whenChanged: #gradientButtonLook inClass: >> PrefProvider notify: self using: #gradientButtonLookIsNow:.>> .... >> ------------- >> >> What do you think ? >> >> cheers >> Alain >> >>>> <Zoo-alain_plantec.10.mcz>_______________________________________________ >>>> Pharo-project mailing list >> [email protected] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project> > >
_______________________________________________ Pharo-project mailing list [email protected] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-projectalain
PrefCore-alain_plantec.1.mcz
Description: Binary data
PrefListener-alain_plantec.3.mcz
Description: Binary data
PrefProvider-alain_plantec.1.mcz
Description: Binary data
PrefTool-alain_plantec.1.mcz
Description: Binary data
_______________________________________________ Pharo-project mailing list [email protected] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
