[Bf-python] Persistent data: new way

Willian Padovani Germano wgermano at ig.com.br
Wed Sep 3 05:16:16 CEST 2003


Hi,

To solve the issue with persistent data, I'm trying this approach, not on
cvs yet:

(apologies for where the inspiration comes from ... : ) and for another long
post)

- Enter the Blender.Registry module -- that can have additional uses later:

Registry contains these functions, all to manipulate a dictionary:

- Keys()
- GetKey (key)
- SetKey (key, dict)
- RemoveKey (key)

Refreshing: in python, dictionaries are sets of pairs (key, value),
where key is a string and value can be any pyobject:
dict = {'key1':10, 'key2':'hello', 'key3':[1,2]}

Simplistic example:

You have a script with 3 configurable parameters in its gui:
- a directory path: mydir = ""
- a filename to save as: myfile = "file.ext"
- a bool to toggle some behavior: doit = 0

Those are the default values, but the user can change them.  To keep these
changes after execution, you can add something like this to your script:

#--------------------------------------
# MyScript
import Blender
from Blender import Registry

# if there's saved data for your script in the Registry,
# get it:

if 'MyScript' in Registry.Keys():
  dict = Registry.GetKey('MyScript')
  mydir = dict['mydir']
  myfile = dict['myfile']
  doit = dict['doit']

else # otherwise use your factory defaults
  mydir = ""
  myfile = "file.ext"
  doit = 0

# ...
# Put your script here
# ...

# in the end:

savedict = {}
savedict['mydir'] = mydir
savedict['myfile'] = myfile
savedict['doit'] = doit

Registry.SetKey('MyScript', savedict)
# -------------------------------------


Note1: first I made Registry.GetKey(key) stop the script with a "not found"
error when the key doesn't exist (like Python does), so that the proper
usage would be:

if 'somekey' in Registry.Keys():
  dict = Registry.GetKey('somekey')
  # get data from dict

but if instead .GetKey(key) returns None for not found keys, then we can
avoid the cost of returning all keys, since this will also work:

dict = Registry.GetKey('somekey')
if dict:
  # get data from dict

Note2: to be on the safer side, never forget to perform type and bounds
checking in variables you recover from the Registry, since they may have
been corrupted by some other script.  Enclosing in a try/except block the
piece of code where you retrieve your data is also a good idea -- any
problem you can warn the user that the saved data was corrupted and use the
default values.

The choice of main key to save your dict is also important.  If you add your
nickname and script version to it, for example, the chance that another
script could overwrite your data *by accident* becomes negligible.  And
anyway, if you check properly, no one will be able to mess with your script
by corrupting/overwriting your Registry key, on purpose or not.  We can
probably also block access to keys that don't belong to your script, if this
proves necessary.  Sheesh, the things we have to worry about : |...

Note3: there's no support yet for storing the Registry data in a file,
though this isn't a hard thing to do.  If we could count on full Python
installations it could be ridiculously trivial, with Pickle/cPickle module.
Maybe with Python 2.3's new import mechanism (zips) or some tweaking in the
linked pythonlib...

Also, Registry is not meant for big chunks of data, it's just for storing
configured gui options.  *Nice* scripts would even check if the data to be
saved is different from the defaults, before trying to store it in the
Registry.  And if equal, remove the key from the Registry, of course.

That's it.  It should be in Blender 2.29, so there's time to change things.
This is open for discussions / suggestions, of course.

--
Willian, wgermano at ig.com.br






More information about the Bf-python mailing list