\c{
When developing complex user interfaces, it will often
be advantageous to do most of the work in the
scripting languages
and to restrict the interaction with the program written
in C++ to a bare minimum.
However, occasionally, the (C++) program will need
to access or modify variables defined in the Tcl script.
To this end, the hush library offers the class var.
}
\sli{
interface var : client {
var(var& v);
var( char* s );
char* operator=(char* s);
char* operator=(int i);
char* operator=(float f);
void trigger(action& ac, char* options = "rwu", char* args = "");
char* name();
char* operator()();
operator char*();
operator int();
operator float();
};
}
\c{
An instance of var may be created
as a reference to an already existing variable
or by giving the name of the variable.
Creating such a variable in C++ has no side-effects.
It does not create or modify a Tcl variable,
it merely provides access to it (if it exists).
A variable may be assigned a value of type
char, int, float or the value of another instance of var.
In the future, other value types may be supported as well.
Variables may be associated with an action
that is triggered whenever one of the operations
read, write or unset as defined by the options
is performed on the variable.
For more details see the Tcl trace command.
The name and (string) value of the variable may be
retrieved by respectively the function name
and the application operator.
In addition for each value type supported
a type conversion operator is supplied.
(No type checking is supported, yet.)
}
\c{
Example
The function inc, shown below,
assumes to have a variable (with value type int) as a client.
It prints the name and value of the variable and
then performs an increment.
}
\sli{
int inc( client* data , kit* tk, int argc, char** argv) {
var x = * (var*) data;
cout << x.name() << " = " << x() << endl;
x = (int) x + 1;
return OK;
}
}
\c{
The function install declares a (Tcl) variable X and
another (Tcl) variable Y.
Further, it associates the function inc (with as client
the variable Y) with the variable X.
When X is assigned a value, due to the association,
the function inc will be invoked (for Y).
Note that the variable for Y is created dynamically,
otherwise the (client) pointer to Y
would be dangling when invoking inc.
In contrast, the variable object created for X may be discarded,
since it is merely used to provide temporary access to
the (Tcl) variable X.
}
\sli{
void install( kit* tk, int, char** ) {
var x("X");
var* v = new var("Y");
action ac(browse,v);
x.trigger(ac,"w");
x = 0; (*v) = 0;
}
}
\c{
The function program also declares a (separate)
var object to give access to (the same) variable X
and uses it as the client for an action installed
as the handler for a button.
Pressing the button will result in calling inc
and, consequently, incrementing
the (Tcl) variable X.
Note, that by associating inc as a trigger action with X,
incrementing X will result in subsequently incrementing Y.
}
\sli{
void program( kit* tk, int, char** ) {
var* v = new var("X");
button* b = new button(".b");
b->text("X++");
b->handler(browse,v);
tk->pack(b)->pack(".quit");
}
}
\c{
No doubt, the reader will need to experiment
to get a feel for the interaction between C++
functions and Tcl scripts.
}
\sli{
int main (int argc, char **argv) {
session* s = new session(argc,argv,"root");
s->install(install);
return s->run(program);
}
}
\c{
To complete the example, the function main
using install and program is pictured above.
}