StateManager -- Save restore program state variables.


package require StateManager

set state StateManager %AUTO% ?options?

$state method ?parameters?

set singleton [StateManagerSinleton %AUTO% ?options?]


While packaged with the ReadoutGUI this is actually a general purpose utility that provides support for Tcl script to save and restore state variables. A state variable can be pretty much anything that might define the state of a program or control how a program operates.

State is saved to and restored from Tcl scripts that consist entirely of set commands. These scripts are sourced into a safe interpreter in order to ensure they cannot damage or inject insecure code into the application itself.

Only pre-declared state variables will be saved or restored from the file, further securing the application script from malicious or erroneous restores.

Note that if an application has several independent components that wish to share a single configuration file, the StateManagerSingleton can be used to provide access to an application speciric singleton state manager object.


StateManager objects include the standard configure and cget methods. These operate on the object option(s) described below.

-file file-path

Provides the path to the file that will be used by save and restore operations.

See METHODS below.


In addtion to the configure and cget methods described in OPTIONS above, the following methods are provided by StateManager objects


Destroys the object.

addStateVariable name getter setter

Defines a state variable that will be saved/restored by the state manager. name is the name of the variable as it will be defined in the file (e.g. set name value).

getter is a command to which name will be appended that will be used by save to obtain the variable value. setter is a command which will be called by restore to restore the value of name. name and value will be appended to the setter command.

If this business of getters and setters is not clear see save and restor and finally the EXAMPLES section below.


Returns a list of the state variables. The return value is a Tcl list of triplets. Each triplet conisists of a variable name, its getter and setter in that order.


Saves the variables to -file. If the -file option is blank an error is thrown.

The save operates by iterating over all registered variables and writing a command that is something like

set varname [getter varaname]

to the file.


Creates a secure slave interpreter and sources -file into that interpreter. For each variable in the list of state variables, if the slave interpreter has a definition for that variable, the setter for that variable is called in code something like this:

$setter $varname $value-in-safe-interp


The example below shows how to define two state variables ::State::var1 and ::State::var2 and their associated getter/setter procs.

Example 1. Getters and setters for StateManager

namespace eval ::State {
    variable var1                                  (1)
    variable var2
proc ::State::getter name {
    return [set ::State::$name]                    (2)
proc ::State::setter {name  value}
    set ::State::$name $value                      (3)

set sm [StateManagerSingleton %AUTO%]
$sm addStateVariable var1 ::State::getter ::State::setter  (4)
$sm addStateVariable var2 ::State::getter ::State::setter

$sm configure -file /path/to/configuration/file.tcl  (5)
$sm save                                             (6)
$sm restore                                          (7)

Creates a namespace for the state variables and declares var1 and var2 which will be saved and restored.
The getter uses the name passed to it, and the fact that the set command without a value just returns the current value of the variable to return the value of the named variable within the ::State:: namespace. Tcl rules for substitution prevent the straightforward use of return $::State::$name
The setter similarly uses the name and value to update the named variable in the ::State namespace.
After getting the state manager singleton, var1 and var2 are registered with getters and setters defined as described above so that each variable is bound to the corresponding variable in the ::State namespace.

It's worth nothing that more interesting setter and getter functions are possible. For example, a setter could load a piece of a graphical user interface, and a getter could retrieva a value from an element of a graphical user interface. The ReadoutShell does this in a few places.

Before doing saves and restores, the -file must be configured to point at a file (or specify a writable file for save) that is used as the target for the save or source for the restore. -file can be freely configured many times. For example your application might prompt the user for a filename into which some configuration information can be written/read.
Saves the values of ::State::var1 and ::State::var2 to the last configured -file. This is done by invoking the getter registered for each of those variables (and any other variables that were added for that matter) in turn passing in var1 and var2 to retrieve their values.
sources the last configured -file into a slave safe interpreter and queries that interpreter to see if each registered variable is defined. For each defined variable, the value is fetched out of the interpreter and that variable's setter is invoked to update whatever in the application is bound to that configuration variable.