---
name: "gk_newenv"
section: "3gk"
platform: "linux"
package: "groupkit"
version: "3.2-1"
release: "Debian 1.3 (Bo)"
platforms: ["linux"]
url: "https://new.carta.tech/gk_newenv"
---

# gk\_newenv(3gk)

create and manipulate shared data

## NAME

gk\_newenv - create and manipulate shared data

## SYNOPSIS

**gk\_newenv** *?-notify? ?-share? ?-client? ?-server? ?-bind? ?-serialize? envName*

## DESCRIPTION

Environments serve to hold pieces of related information within a single data structure, and optionally share that data between different processes.  Environments are hierarchically structured dictionaries.  Information in an environment is accessed via a key, which specifies where within the environment information is stored. Because environments are hierarchical, keys serve to encode this hierarchy.  Keys use a period (".") as the hierarchy delimeter. For example, the key "local" refers to information at the first level of the hierarchy, whereas the key "local.name" refers to information deeper in the hierarchy.

Environments are created with the **gk\_newenv** command, which specifies a name for the environment.  This creates an  *environment command*, similar to Tk's widget commands, which is used to manipulate the environment.

The behavior of environments can also be manipulated by the application program, so that a particular instance of an environment may act radically different from what is described here.  The section on customizing environments explains this.

## ENVIRONMENT COMMAND

The **gk\_newenv** command creates a new Tcl command whose name is *envName*.  This command may be used to invoke various operations on the environment.  It has the following general form:

*envName option ?arg arg ...?*

The following subcommands are defined for standard environments:

- *envName* **set** *key value*

  Store information specified by *value* into the environment at  *key*.  *value* should represent only simple data; use the **import** subcommand to insert a tree of information.  In the case where *key* does not specify any other subcommand defined for the environment, the keyword **set** may be omitted.

- *envName* **get** *key*

  Retrieve the information stored in the environment at *key*. If *key* represents a hierarchy of information, it is returned as a keyed list.  If the *key* does not exist in the environment, an empty string is returned.  In the case where *key* does not specify  any other subcommand defined for the environment, the keyword **get** may be omitted.

- *envName* **keys** *?basekey?*

  Display the names of the keys directly underneath *basekey* in the  environment.  If *basekey* is omitted, display the names of the keys at the root level of the environment.

- *envName* **delete** *key*

  Delete the information contained within *key*.  Deleting a key which itself is a parent of other keys deletes all the information in the hierarchy.

- *envName* **exists** *key*

  Determine if *key* exists in the environment.  Returns 1 if *key* exists, 0 otherwise.

- *envName* **import** *basekey data*

  Import a collection of information, specified as the keyed list *data* *Note that data* is passed by value, not by reference, which differs from most of the standard commands for manipulating keyed lists.

- *envName* **destroy**

  Destroy the environment, its associated data, and the environment command.

- *envName* **debug**

  Display the contents of the environment on stdout, for debugging purposes.

- *envName* **option** *args...*

  Store option information in the environment.  Essentially, this  command allows access to a separate space within the environment designed for storing information about the environment's behavior, as described in the section below on customization.  The option space works similarly to the conventional data space.  The **option** subcommand has the following forms:

-

  ```
    envName option set key value
    envName option get key
    envName option delete key
    envName option keys ?key?
  ```

- *envName* **command** *args...*

  This subcommand is used to modify the behavior of the environment,  by manipulating the environment command's subcommands.  Its use is described in detail below, in the section on customizing environments.

## ENVIRONMENT EVENTS

If the *-notify* switch is specified when an environment is created with **gk\_newenv**, the environment will generate events whenever its contents are modified.  This provides a convenient way for you to model information; changes in the environment (the model) can  generate events which will then propagate to change your interface (the view).

Environments will generate three types of events: **addEnvInfo** (when new information is added to an environment), **changeEnvInfo** (when existing information in an environment is changed), and **deleteEnvInfo** (when information in an environment is deleted). In addition to the event **type** attribute, each of these events also contains an **env** attribute giving the name of the environment where the change occurred, and a **key** attribute describing where within the environment the change occurred.

Alternately, events may be generated using a different mechanism, more analogous to Tk's bind command.  If *-bind* is specified rather than *-notify*, the events will be generated using the notification mechanism described in gk\_notifier(n).  In that case, the following subcommands are available in the environment:

- *envName* **bind** *event command*

  Arrange for *command* to be executed when an event having the type specified in *event* (e.g. addEnvInfo) is generated.  If the  string "%K" appears in *command*, it will be replaced with the key attribute of the event.  This command returns a token which can be used to remove the binding.

- *envName* **delbind** *binding*

  Remove an event binding, where *binding* is the token returned when the binding was first created.

## SHARED ENVIRONMENTS

If the *-share* switch is specified when an environment is created, the environment will be shared between GroupKit conference processes. The sharing supported by this form of environments does not support any form of concurrency control; it is quite possible for copies of the environment on two different processes to get out of sync.  This may in fact not be a bad thing for certain applications, and certainly reduces the overhead and delays inherent in keeping data correctly synchronized.

This version of environments uses the following mechanism for sharing. Whenever a change is made to an environment in any of the conference processes, that change is broadcast to all copies of the environment, via a gk\_toAll(n) call.  This can lead to race conditions.  For example, if process A changes the value X to 3, at the same time process B changes X to 5, the following can occur.  Each process will execute the change locally (leaving X at 3 on process A and at 5 on process B), and then send the change to the other process.  The end result will be that X has the value 5 on process A, and the value 3 on process B.

Sharing becomes quite useful when combined with notification.  If both *-share* and *-notify* (or *-bind*) are specified, events will be generated whenever the environment changes, whether the change was initiated by the local user or a remote process.  Applications can take advantage of this by tying their display to events generated by the underlying environment which is used to model the abstract application data.

Shared environments generate one additonal event, **envReceived** **a new user joins an existing GroupKit session, one of the existing** **users is chosen (via the updateEntrant mechanism) to send a copy of the** **data already existing in the environment to the newcomer.  On the** **receiving end, this will generate an envReceived** event.  The application will typically need to traverse the environment, for example to create objects on the display that mirror those in the environment.

## CENTRAL SERIALIZED CONCURRENCY CONTROL

A version of shared environments are available for cases where a  centralized process is available to manage concurrency control. These environments are therefore not suitable for use in GroupKit conferences, where no such process exists.  They are used however by GroupKit's registration system, as well as the rooms based registration client.

The environment must first be created on the centralized process. This environment is created using the *-server* option.

Environments that connect up to the centralized process are referred to as client environments, and are created using the *-client* option.  After creation, they must then be "attached" to the  centralized server process using the following command.

- *envName* **server** *fd*

  Connect to the centralized server environment, where *fd* specifies the file descriptor used to send messages to the server process.

Serialized environments work by sending all changes through the centralized process, which then redistributes them to all clients. In this way, changes arrive in the same order on all processes. However, there can be a substantial time delay between when a change is made locally to the environment, and when it takes effect, after the round trip to the centralized server process.

## CONFERENCE SERIALIZED CONCURRENCY CONTROL

The final variation on environments is used to provide a serialized concurrency control implementation (as used in the centralized process version described above), but within GroupKit conferences.  In this case, one of the users in the conference is chosen as the "central" processes to centralize changes through.  This "centralized process" may change as users enter and leave the conference.  To use this form of concurrency control, the *-serialize* option is used when creating the environment.  This may also of course be combined with *-notify* or *-bind*, but not with *-share*, *-server*, or *-client*.

## CUSTOMIZING ENVIRONMENTS

It is possible to customize the behavior of environments, by modifying the subcommands available to the environment.  More detail and rationale are described in the paper "When is an object not an object?".

The following environment subcommands are available for customizing environments.

- *envName* **command set** *cmdname script*

  Specify that *script* is to be invoked whenever a command of the form *envName cmdname args...* is executed.

- *envName* **command get** *cmdname*

  Return the script that is to invoked whenever the subcommand *cmdname* is executed in the environment.  For subcommands not having a Tcl script associated with them (i.e. they are handled by C code), the string "\<builtin\>" is returned.

- *envName* **command delete** *cmdname*

  Remove any handler associated with the subcommand *cmdname*,  making the subcommand invalid.

- *envName* **command list**

  Return the list of valid subcommands for the environment.

- *envName* **command rename** *oldname newname*

  Associate the handler currently attached to *oldname* with the subcommand specified by *newname*.  The *oldname* subcommand is still available with the same handler.

## SEE ALSO

gk\_event(n), gk\_notifier(n), gk\_runtime(n)

Roseman, M. "When is an object not an object?"  Proceedings of the 1995 Tcl Workshop.

## AUTHOR

Mark Roseman (roseman@cpsc.ucalgary.ca)
