Stéphane
your previous question makes me think of a better solution
with 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.

>
> Sorry not to reply earlier (I was breaking yet another wall in our > "kitchen")
bon courage :)
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-project





alain

Attachment: PrefCore-alain_plantec.1.mcz
Description: Binary data

Attachment: PrefListener-alain_plantec.3.mcz
Description: Binary data

Attachment: PrefProvider-alain_plantec.1.mcz
Description: Binary data

Attachment: 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

Reply via email to