This site has been retired. For up to date information, see handbook.gnome.org or gitlab.gnome.org.


[Home] [TitleIndex] [WordIndex

Notes about the changes caused by the fix for bug 381323.

Summary

Previously, Setting objects were brought into existence only when the settings dialog was shown to wrap standard Python attributes on the AEState class for configuration. Now the Setting objects exist for the lifetime of the AEState object and replace the use of raw Python attributes for user configurable settings. This change lets us:

Changes to Perks

The attributes on PerkState objects should no longer be initialized as class variables. Instead, there is now an init() method that you can populate with calls to new* to create setting objects. The getSettings() method is replaced with getGroups() which just returns a group constructed using newGroup() containing other groups and the names of configurable settings.

   1 class MyPerkState(Perk.PerkState):
   2   def init(self):
   3     self.newBool('IsCool', True, 'Is LSR cool?', 'Why would you ever unset this?')
   4     self.newRange('HowCool', 100, 'How cool?', 0, 100, 0, 'How cool is LSR?')
   5 
   6   def getGroups(self):
   7     root = self.newGroup()
   8     g = root.newGroup('LSR Coolness')
   9     g.append('IsCool')
  10     g.append('HowCool') # can also do g.extend(['IsCool', 'HowCool'])
  11     return root

All new* methods now take a final optional parameter named 'persist' (defaults to True). If set to False, the setting value will never be written to disk.

Access to the values of these settings can still be accomplished like so:

   1 self.perk_state.HowCool += 1

You can also gain access with the following methods:

   1 val = self.perk_state.getSettingVal('HowCool')
   2 self.perk_state.setSettingVal('HowCool', val+1)

Since the setting objects are alive "forever" now, you can also fetch the Setting instances:

   1 s = self.perk_state.getSettingObj('HowCool')
   2 print s.max, s.min, s.label, s.description, s.value

For range settings, bounds checking is performed automatically when the 'value' property of a setting is assigned. If the value is outside the allowed bounds, it is snapped to the closest bound automatically without error. You will still get a TypeError in most cases if you try to assign a value that cannot be converted to a proper type for the setting (e.g. None).

Changes to Devices

All the information about states/settings in Perks apply to devices, with the following additional notes.

The init method on a style takes one additional parameter: a reference to the corresponding device after it is initialized. This reference can be used to dynamically detect settings at runtime if needed. The reference should not be stored in an instance variable as it will prevent proper garbage collection when the device is unloaded.

All devices now must define a STYLE class variable pointing to the subclass of AEOutput.Style that will serve as the state object for the device. FLYWEIGHT_STYLE is no longer needed. The trick is to make sure flyweights override certain settings when they might differ per semantic tag and do not override others when the default is all that is needed. This is easily accomplished with logic like the following:

   1 class MyStyle(AEOutput.Style):
   2   def init(self, device):
   3     self.newBool('Invert', False, 'Invert?', 'When set, inverts the current zoom region.')
   4     if self.isDefault():
   5       self.newBool('Kinematics', False, 'Smooth panning?', 'When set, all zoom regions pan smoothly instead of warping')

In this case, Invert is available on all style objects (possibly one per zoom region) while Kinematics is only available on the default (affecting all zoom regions).

The AEOutput.Style class defines three additional new* methods for creating relative ranges: newRelPercent, newRelNumeric, and newRelRange. When these settings are in a Style instance that is not the default (i.e. any style with a reference to the default), the value of the current setting adds to the value in the default. This is used for speech pitch, rate, and volume such that changing the value in the default causes a relative change in all voices. It may or may not find use for other devices.

Finally, when implementing a createDistinctStyles method and constructing new Style objects, be sure to call init() on any new styles. Otherwise, settings for these styles will not be created.

See IBMSpeech for the shining example of a device that supports the new AEState system. You may also look at GSpeech, but realize it is far more complex because it is a generic interface to any number of other speech engines (i.e. it's settings must be built dynamically).

The CliqueAudio and SpeechDispatcher devices have not yet been updated for new AEState. See bug #383815.


2024-10-23 10:59