A Flexible Graphical User Interface for

SOFTWARE—PRACTICE AND EXPERIENCE, VOL. 25(2), 193–216 (FEBRUARY 1995)
A Flexible Graphical User Interface for Performance
Modeling
YI-BING LIN AND DAN DALY
Bellcore MRE 2D-297, 445 South Street, Morristown, NJ 07960-1910, U.S.A.
SUMMARY
We identify three goals for the graphical user interface (GUI) of a network simulation environment: user
friendliness, model re-usability, and application extensibility. We address the user-friendliness issue by
proposing a simple yet efficient approach to setup parameters for the simulation models. We address the
application extensibility issue with a two-layer GUI architecture. The two layers are loosely coupled, and
the first layer can be easily replaced without affecting the other components of the simulation environment.
The concept of subnetwork is used to address the model reusability issue. Unlike most existing simulation
packages, where a subnetwork is simply a method to group the nodes, the subnetwork construct in our
approach is a first-class citizen in the simulation environment (i.e., all operations for a basic node also
apply to a subnetwork). The port concept is used to define the I/O relationship between a subnetwork
and the outside world. Parameter dialog boxes are used to set up the parameters for a subnetwork
conveniently. Finally, a simple stack mechanism is used to measure subnetwork-wide output statistics.
KEY WORDS: application extensibility; graphical user interface; model reusability; parameter dialog box; sub-network;
user friendliness
1.
INTRODUCTION
Most modern simulation environments include a graphical user interface (GUI) to simplify
the task of building the system under study. A simulation environment usually provides
methods for the user to develop elementary components. These elementary components
are represented by icons in the GUI, which allow the user to construct complex models
graphically with little or no programming effort. Three goals should be achieved for a GUI
design:
1. User friendliness. The GUI should provide an obvious, intuitive, and consistent interface to the simulation system. Most GUIs provide convenient operations to build
a model system. However, setting parameters for a model component is usually a
tedious process. (An elementary component is associated with some parameters that
must be set before the simulation execution. The possible parameters for an element
such as a queue are scheduling policy, number of servers, service distribution, and
so on.) In simulation packages such as ObjectTime,1 the parameter setup is done
by modifying the C++ code for the element. For packages such as Q+2 or Opnet,3
convenient methods are provided to set some pre-defined parameters. However, for
the user-defined parameters, it is necessary to modify the code for the elements. In
CCC 0038–0644/95/020193–24
1995 by John Wiley & Sons, Ltd.
Received 11 August 1993
Revised 5 October 1994
194
Y.-B. LIN AND D. DALY
Figure 1. Graphical layouts for different applications
this article we show how to design a user-friendly GUI with convenient methods for
setting up parameters.
2. Model reusability. The GUI should provide an efficient means for reusing component models. This is often done with subnetworks (or sub-models). The subnetwork
construct in most simulation packages is just a method of grouping basic elements
together. The construct is difficult to use if the subnetwork needs to be modified before it can be included in other systems. This article will propose a better subnetwork
construct to promote model reusability.
3. Application extensibility. The GUI should provide different graphical layouts for different types of simulation applications. For example, the graphical layout for a 4-node
queueing network (see, Figure 1(a)) is very different from a 4-cell mobile phone
system4 (see, Figure 1(b)). (The concept of ‘layers’ in this figure will be described
later.)
The GUI structure should be flexible enough to accommodate graphical layouts for
different applications.
To achieve these goals, we propose a flexible GUI structure for performance modeling
(referred to as GUI/PM). The GUI/PM concept was implemented in a simulation environ-
A FLEXIBLE GRAPHICAL USER INTERFACE
195
Figure 2. The layers of a flexible graphical user interface design.
ment called COPS (computer operations performance simulation system).5 The GUI/PM is
a two-layer structure as shown in Figure 2: Layer 1 implements all graphics-related functions. Layer 2 implements all model setup code to be executed by a simulator. (In COPS,
Layer 2 is written in C++ to be compatible with the simulator). These two layers are run on
different processes (and even in different machines) and communicate by message passing.
Basically, Layer 1 acts simply as a filter between the user and Layer 2 (the graph application). Layer 1 has no knowledge of the application nor the consequences of the actions
performed by a user. It works hand in hand with Layer 2, which interprets the user’s input
and determines proper responses to this input. Thus, the role of Layer 1 is simply to notify
Layer 2 of a user’s actions, placing the responsibility of responding to these actions to the
Layer 2 process. Layer 2 keeps a registry of all active data objects currently being represented by graphical objects in Layer 1. Since the graphical objects correspond to objects in
the application domain, a user action on an active graphical object can be mapped directly
to an action on an application object. The correct response to a user action thus depends
on the graphical object to which the user’s action was addressed.
The sequence of user action and system response is a communication between a Layer 1
process and a Layer 2 process. After the user initiates an action via Layer 1, Layer 1
informs Layer 2 which action was taken and on which graphical object. Layer 2 will then
consult its database and determine an appropriate response for that action. Responses include
acknowledgment of the action, creation of a new graphical object (if a data object is created
at Layer 2), destruction of an already existing graphical object (if the corresponding data
object at Layer 2 is deleted), or having Layer 2 relay an error message to the user. This
response is then sent back to Layer 1, which then carries out the response as instructed.
Separating the task of accepting user input from determining system response makes the
GUI quite general. This loosely-coupled two layer approach has several advantages:
1. It is convenient to implement Layer 1 and Layer 2 in different languages. Usually,
Layer 2 and the simulator are implemented in the same language (e.g., C++ in COPS).
In general, the language for the simulator is not the best language to implement
Layer 1. With our two layer structure, the graphical functions for Layer 1 can be implemented using a different language (e.g., in COPS, Tcl,6 Unidraw,7 and HP InterViews8
and Penguin/Collage9 have been used to implement Layer 1). An obvious advantage
196
Y.-B. LIN AND D. DALY
is that this structure promotes portability. Different computing environments may not
use the same window system. Migrating a simulation environment from one window
system to another may require major modifications. With the two-layer GUI structure,
the modification effort is minimized. Only part of Layer 1 needs to be changed. The
other components of the simulation environment are not modified.
We note that in the two layer structure, the callback function invoked by a graphical
object (in Layer 1) simply prints a string (the command to be sent to Layer 2). The
string (command) is then used by Layer 2 to operate on complex objects (or data
structures) that may be difficult to implement using the language of Layer 1.
2. More than one Layer 1 can be attached to a Layer 2. Since Layer 1 and Layer 2
are executed by different processes, we may invoke multiple Layer 1 processes to
communicate with one Layer 2 process. This feature promotes teamwork. Users in
remote locations can invoke Layer 1 processes for the same Layer 2 process. When a
user takes an action, the command is received by the Layer 2 process and is reflected
to the other Layer 1 processes. Thus, users in remote locations may co-operate to
build a simulation model.
3. The GUI can be easily modified to accommodate different applications. Consider the
examples in Figure 1(a) and (b). Although the graphical layouts are different for the
two applications, the commands sent to Layer 2 to construct the models are very similar
(see, Figure 1(c) and (d)). Thus, we only need to modify Layer 1 to accommodate
different simulation applications (and Layer 2 is still the same).
This article illustrates these design ideas with a prototype developed at Bellcore. One may
re-implement these design ideas with different implementation alternatives.
2.
GRAPHICAL LAYOUT FOR GUI/PM
When a user first starts up the GUI, a graphical editor such as the one illustrated in Figure 3
appears. This editor is referred to as the main graphical editor.
The graphical editor in Figure 3 is a standard COPS GUI for a simple queueing network
application with three types of nodes: Source, Sink, and Queue. In this example, a node
type is an elementary component described in the previous section. The graphical editor
consists of three areas, a canvas area in which the user interacts directly with the graphical
object (e.g., a node), a palette area in which a user can select tools to interact with graphic
objects (e.g., create a new node, rotate, move, zoom, pan, etc.), and a menu bar for other
functionality such as file operations, editing operations (e.g., cut/paste), etc. In the node
selection part of the palette area, in addition to the three basic node types ‘SO’ (source),
‘SI’ (sink), and ‘Q’ (queue), there is a fourth item representing a subnetwork, which can be
used to construct a queueing network hierarchically (the details of subnetwork are discussed
in Section 6). To create a node, the user selects a node type in the node selection area and
places an instance node of the type in the canvas area (see, Figure 3). The user may
implement a new node type and include it in the node selection area. The ‘Port’ operations
in the menu bar allows the user to create ports for a node (see, in Figure 3, the node
‘Queue’ has two ports out1 and out2). The nodes can be connected through ports using the
link operation in the palette area.
A node is associated with a set of input parameters. For example, a node of type Queue
may have the following input parameters (see Figure 4): Server No., Scheduling Policy (e.g.,
First-In-First-Out, Non-Preemptive Priority, Preemptive Priority), Output Measures (e.g.,
A FLEXIBLE GRAPHICAL USER INTERFACE
197
Figure 3. The main graphical editor
utilization, response time, queue length, throughput), and Job-Type. The Output Measures
parameter allows the user to select the output statistics to be displayed in real time. The JobType parameter is used to specify the parameters for different types of jobs. For example, in
a computer system there may be two types of jobs: batch jobs and interactive jobs. Different
types of jobs may have different priorities, service time distributions, and routing patterns
for a queue node. It is important that the GUI provide convenient ways to set up these
parameters. In simulation packages such as ObjectTime,1 the parameter setup is done by
modifying the C++ code for the node. Packages such as Q+2 or Opnet3 provide convenient
ways to set some pre-defined parameters. However, for the user-defined parameters, it
is necessary to modify the code for the node. In GUI/PM, all parameters are accessed
graphically through dialog boxes as shown in Figure 5. These dialog boxes are referred to
as parameter dialog boxes or (PDBs). Existing simulation packages do not follow GUI/PM’s
approach because it is difficult to implement the PDBs when a user implements a new node
type. The user may not know how to write the graphic code to generate the PDBs. GUI/PM
overcomes this difficulty by automatically generating the PDBs when a user implements a
new node type.
3.
SPECIFYING THE PARAMETER DIALOG BOXES
GUI/PM supports three graphic data structures for PDBs: data set, data table, and data
graph. We first define these data structures and then show how to specify PDBs (e.g., to
include a button in a data set).
1. Data Set is used to represent a set of data items that are displayed to the user through a
Motif style dialog box. Examples of data sets (sets of data items) are Queue Parameters
198
Y.-B. LIN AND D. DALY
Figure 4. The input parameters for a Queue node
in Figure 5(b), Service Time Distribution in Figure 5(d), and Output Measures in
Figure 5(f).
GUI/PM supports four types of data items. An entry data item consists of a label
and a text editing area (see, the Server No. parameter in Figure 5(b) and Parameter 1
and Parameter 2 in Figure 5(d)). A radio data item consists of a label and a set of
radio buttons (i.e., a set of toggle buttons configured so that only one in a group of
buttons can be chosen). Examples are the Scheduling Policy parameter in Figure 5(b)
and the distribution selection in Figure 5(d) (in this example, the label is omitted).
A check data item consists of a set of check boxes (i.e., toggle buttons where the
user can select any option that applies). Examples are the check boxes in Figure 5(f)
(where the label is omitted). A button data item is a push button with a label inside
the button. Examples are Job-Type and Output parameters in Figure 5(b). When a
button is pressed, some action is taken. For example, pressing the Job-Type button in
the Queue Parameters PDB will bring up the Job-Type PDB as shown in Figures 5(b)
and (c). A special button ‘OK’ is associated with every PDB. When this button is
pressed, the PDB disappears.
2. Data Table is used to represent an array of editable data that are displayed to the user
through a motif style dialog box. Examples of data tables are shown in Figures 5(c)
and (e). The data concept is much like a relational database system where each row of
the array represents a single record of data and each column represents a field within
the data record. Each record has a name (key) field that uniquely identifies the record.
Buttons are provided to add, delete, select, and rename a record. Some data items
(such as Routing Table and Service Time buttons) are attached to receive additional
information about a record.
Conceptually, a record can be viewed as a data set. (Indeed, at Layer 2 of a GUI/PM,
records of a table set are implemented as data sets.) For example, the first record in the
A FLEXIBLE GRAPHICAL USER INTERFACE
199
Figure 5. The parameter dialog boxes for a queue node. (a) is a data graph; (b), (d), and (f) are data sets; and
(c) and (e) are data tables.
Job-Type PDB (see Figure 5(c)) can be viewed as a data set named ‘batch’ consisting
of an entry item Priority and two button items Routing Table and Service Time. If
we select the batch record and press the Routing Table button, then the Routing Table
PDB (see Figure 5(e)) for batch job type appears.
3. Data Graph is the means by which a user may interactively manipulate the elements
of a graph. It allows creation, deletion and movement of elements and links. An
example is the main graphical editor shown in Figure 3. Data graph can also be
used to set up complex data structures for a node type. For example, a queue node
uses a linked list data structure to buffer the arriving jobs. At the beginning of the
simulation, we may want to set up some jobs waiting in the queue. Thus, we may add
200
Y.-B. LIN AND D. DALY
Figure 6. Set up Queue’s linked list using data graph.
a Queue-Initialization button in the Queue Parameters PDB (to be described in the
next section). When the button is pressed, a graphic editor is brought up as shown in
Figure 6. Then the user can set up the linked list data structure graphically.
Note that the parameters of packets (i.e., jobs), such as service time, packet type, and
routing information can be set up by providing a PDB for the packet element. In other
words, the procedure we use to set up a system through the main graphical editor
(see Figure 3) also applies to the setup of a complex data structure for an elementary
component. Note also that in Figure 6, a port of a packet cannot link to more than two
packets. If the user tries to do so, he will receive an error message. The data graph
can be set to limit the connectivity of a directed graph. Moreover, some operations
(such as ‘add port’, ‘delete port’) can be disabled.
Data graph can implement the subnetwork concept (to be described in Section 6) as
well. In the current implementation, a user-defined data graph is restricted to graph-like
layouts (i.e., nodes connected by links).
GUI/PM provides an interactive PDB specification tool (PDB-ST) for specifying the PDBs.
Based on the specifications, PDBs are automatically generated by the GUI/PM. Figure 7
illustrates how to use PDB-ST to specify the PDBs for the Queue type. In our implementation, PDB-ST is a line editor.∗ In fact, all the dialog boxes of the graphical PDB-ST can be
automatically generated by using the text PDB-ST. In this figure, the roman font characters
represent the prompt of PDB-ST, and the typewriter font characters represent the input
from the user.
PDB-ST first asks for the name of the object type to be created, the base object type
(from which the new object type is derived), and the label (to be used as the PDB title).
Based on the inputs in Figure 7, PDB-ST automatically creates sets of C++ code used by
the GUI/PM to produce a graphical layout as shown in Figure 5(b).
∗
Note that it is not difficult to implement a graphical PDB-ST as a part of the GUI/PM.
A FLEXIBLE GRAPHICAL USER INTERFACE
1. Class Name: Queue
2. Base Class: DataSet
3. Label: Queue Parameters
——–Parameter 1——–
4. Name: Server No.
5. Class: IntEntryDataItem
6. Default Value: 1
7. Variable Name: num
——–Parameter 2——–
8. Name: Scheduling Policy
9. Class: RadioDataItem
10. Value Set: FIFO, NPP, PP
11. Default Value: FIFO
12. Variable Name: sp
——–Parameter 3——–
13. Name: Job-Type
14. Class: JobTable
15. Variable Name: jT
——–Parameter 4——–
16. Name: Output
17. Class: QueueOutput
18. Variable Name: output
(a) Specifying the Queue Class
19.
20.
21.
22.
201
Class Name: JobTable
Base Class: DataTable
Label: Job-Type
Record: JobRecord
(b) Specifying the JobTable Class
23. Class Name: JobRecord
24. Base Class: DataSet
25. Label: Name
——–Parameter 1——–
26. Name: Priority
27. Class: IntEntryDataItem
28. Default Value: 1
29. Variable Name: pr
——–Parameter 2——–
30. Name: Routing Table
31. Class: RoutingTable
32. Variable Name: rT
——–Parameter 3——–
33. Name: Service Time
34. Class: ServiceTime
35. Variable Name: sT
(c) Specifying the JobRecord Class
Figure 7. Specifying the PDB for the Queue type
Consider Figure 7(a). The user first specifies the name of the C++ class of the PDB
(see line 1) and the base class from which the PDB class is derived (see line 2). The
base class can be IntEntryDataItem, FloatEntryDataItem, StringEntryDataItem,
RadioDataItem, CheckDataItem (the C++ classes for entry, radio, and check data items),
DataSet, DataTable, DataGraph (the C++ classes for data set, data table, and data graph),
or any class derived from DataSet, DataTable or DataGraph. The behavior of PDB-ST
depends on the base class specified. For example, if the base class is DataSet or a derived
class of DataSet, PDB-ST asks the user to specify the label (i.e., the title of the PDB; see
line 3) and the parameters (i.e., data items; see lines 4–18).
For every parameter, PDB-ST asks the user to specify the name (see line 4) and the
C++ class (see line 5). The specification of the parameter depends on the C++ class and is
described below.
1. IntEntryDataItem: the user is asked to specify the default value (see line 6) and
the variable name (see line 7). The variable name is an integer C++ variable used
in the simulation code. The specification of Parameter 1 in Figure 7(a) results in the
Server No. text entry in Figure 4(b).
202
Y.-B. LIN AND D. DALY
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
class DataSet : public Object {
protected:
ParameterList *parList;
int windowId;
public:
DataSet();
... /* other house-keeping functions */
virtual void CreatePDB()=0;
void ModifyPDB(String command);
void LoadConfigFile(FILE *fp);
void StoreConfigFile(FILE *fp);
};
Figure 8. The DataSet definition
2. RadioDataItem: in addition to the default value and the variable name, the user also
specifies the Value Set, the names of the radio buttons. The specification of Parameter
2 in Figure 7(a) results in the Scheduling Policy radio button set in Figure 4(b).
3. data set, data table or data graph or any derived class of these three classes: the user
only specifies the variable name (see lines 13–15). The parameter is considered as a
button data item. The specification of Parameter 3 in Figure 7(a) results in a button
in the Queue Parameters PDB (see the Job-Type button in Figure 4(b)). The PDB
(see, Figure 4(c)) associated with the button is also specified using PDB-ST. The
specification of the PDB for Parameter 3 in Figure 7(a) is given in Figure 7(b). The
class JobTable is derived from DataTable.
For a class derived from a data table, the user needs to specify the name of the record
(see line 22) in addition to the label of the PDB (see line 21). Since a record is a data
set, a separate JobRecord data set specification is given in Figure 7(c).
PDB-ST maintains the relationships among the classes specified. For example, after
the record name JobRecord is specified, PDB-ST reminds the user to specify the
JobRecord class before the PDB-ST session ends.
The detailed specifications for data graph were given in.10 Basically, several default operations (such as file, edit, and port operations in Figure 6) are automatically included when a
data graph is specified. Some of the operations can be suppressed, and new operations can
be added in the option menu. The user may include node types and their icons. The user
is required to write C++ code for a new node type (or simply include the class name of
an existing node type). The icon of a node type can be created using the standard UNIX
bitmap tool.9
4.
AUTOMATIC CODE GENERATION FOR PDB
This section uses the queue PDB as an example to illustrate how PDB-ST generates the
C++ code for a PDB. The reader is assumed to understand the C++ language. We first
describe the C++ DataSet class (see Figure 8 for the DataSet definition). In DataSet, a
linked list data structure ParameterList (see line D3) is used to hold the data items in
the data set. An example of ParameterList with four elements is given in Figure 9.
A FLEXIBLE GRAPHICAL USER INTERFACE
203
Figure 9. An example of ParameterList
Initially, an empty linked list parList is created in the DataSet constructor (see line D6;
the details of this function are not given). DataSet also uses an integer variable windowId,
which will be discussed in Section 5.
There are four basic functions. Two of the functions,
LoadConfigFile and StoreConfigFile
(see lines D10 and D11), are used to load/store the model from/to a file. These functions
are automatically generated by PDB-ST and will not be discussed further. The CreatePDB
function (see, line D8) is an abstract function. Its implementation depends on the derived
class. The ModifyPDB function sets/modifies the value of a parameter in the data set.
Figure 10 gives the definition for Queue (the definition and the implementation of Queue
are generated by PDB-ST). Based on the specifications in Figure 7(a) (see, lines 7, 12, 15,
and 18), PDB-ST produces four variables for Queue (see lines Q3–Q6). The implementation
of the Queue constructor (see line Q9) is given in Figure 11. At line X1, the Queue constructor first invokes the DataSet constructor to create/initialize parList and other housekeeping variables. Then it initializes the integer num based on line 6 in Figure 7(a). Similarly,
sp is initialized based on lines 10 and 11 of the specification in Figure 7(a). At lines X2
and X3, a JobTypeTable and a QueueOutput are created and pointed to by jT and output,
respectively. Lines X4–X7 add the four data items into parList. A parameter in parList
consists of three fields (see, Figure 9): The type field specifies the type of the parameter
(there are nine types of parameters: INT PAR, FLOAT PAR, STRING PAR, RADIO PAR,
CHECK PAR, DATA SET PAR, DATA TABLE PAR, DATA GRAPH PAR, and PTR PAR; the type
PTR PTR will be discussed in Section 6), the name field specifies the parameter name, and
the ptr field specifies the pointer to the corresponding variable. After lines X4–X7 have
executed, four elements are inserted in the linked list (see Figure 9).
To generate the graphical layout for Queue Parameters PDB, Layer 2 sends a sequence
of strings (see Figure 12) to Layer 1.
In the figure, the number 2 at the first line represents the window id for the data set
(to be discussed in the next section). Based on these strings, Layer 1 generates the PDB
given in Figure 5(b). Layer 2 generates these strings by invoking the Queue’s CreatePDB
function as shown in Figure 13. The Queue class inherits the ModifyPDB function from
DataSet. When the user modifies the PDB by pressing a button on the screen, Layer 1
sends a command to Layer 2. The corresponding PDB data structure (e.g., Queue) in Layer 2
is identified, and the ModifyPDB function of the PDB is invoked. The implementation of
204
Y.-B. LIN AND D. DALY
Q1 class Queue : public DataSet {
Q2
protected:
Q3
int num;
Q4
RadioButton sp;
Q5
JobTypeTable *jT;
Q6
QueueOutput *output;
Q7
public:
Q8
Queue();
Q9
void CreatePDB();
Q10
... /* house-keeping variables/functions */
Q11 };
Figure 10. The Queue definition
ModifyPDB is given in Figure 14. Based on the information encoded in the string command,
the GetParameter function searches parList to identify the corresponding parameter (see
line S2). The parameter setup operations are different for different types of parameters. If
the parameter is a data item, then the value encoded in command is extracted and assigned
to the corresponding variable (see lines S4–S13). If the parameter represents a PDB, the
corresponding CreatePDB function is invoked to generate the graphical layout for the PDB
(see lines 14–19).
All the implementations of the C++ classes mentioned in this section are generated by
GUI/PM and are transparent to the user. The user only needs to connect variables such as
num and sp to the simulation functions he writes.
5.
IINTERACTIONS BETWEEN LAYER 1 AND LAYER 2
This section describes the interactions between Layer 1 and Layer 2. Layer 2 runs in a
loop, waiting for commands from Layer 1 (see, Figure 15). When a command arrives (see
line L2), Layer 2 interprets the commands (lines 3 and 4) and sends a textual reply back to
Layer 1 (line 5; the details are not shown). Layer 2 maintains a linked list called ‘Object
List’ to keep track of the Layer 2 objects whose corresponding Layer 1 graphical objects
X1
X2
X3
X4
X5
X6
X7
X8
X9
Queue::Queue() : DataSet(), num(1), sp("FIFO","NPP","PP","FIFO"): {
JobTypeTable *jT = new JobTypeTable();
QueueOutput *output = new queueOutput();
parList->AddParameter(INT_PAR, "Server No.", &num);
parList->AddParameter(RADIO_PAR, "Scheduling Policy", &sp);
parList->AddParameter(DATA_TABLE_PAR, "Job-Type", jT);
parList->AddParameter(DATA_SET_PAR, "Output", output);
... /* other house-keeping operations */
}
Figure 11. The Queue constructor
A FLEXIBLE GRAPHICAL USER INTERFACE
205
DATASET { 2, Queue Parameters;
ENTRY (Server No., 1)
RADIO (Scheduling Policy, <FIFO, NPP, PP>, FIFO)
BUTTON (Job-Type)
BUTTON (Output)
}
Figure 12. The strings produced by the CreatePDB function
are active. Several objects may be active at the same time. An element in the list is a pointer
to a Layer 2 object such as a data set.
The elements in the Object List are distinguished by the window identifiers (ids) of the
objects pointed to by the elements. Figure 16 illustrates the Object List and the corresponding graphical objects in the canvas area of the main graphical editor. A black box
represents an element in the Object List. For demonstrational purposes, the window id of
the corresponding object is shown inside the black box, and for an active graphical object at
Layer 1, we treat the corresponding Layer 2 object as an element inserted in the Object List
(although the element is in fact a pointer to the object). A positive window id is assigned
to a Layer 2 object when the object is inserted into the Object List. When the object is
deleted from the list, its window id is set to −1. If the object is inserted into the Object
List again, a (possibly) different positive window id is assigned to the object.
All objects in the list have different window ids. In the current implementation, the Object
List uses a simple linked list data structure. Sophisticated data structure such as binary tree
can be used to speed up the insertation and the deletion operations.
The main graphical editor is brought up when a user starts the GUI.
The data graph corresponding to the main graphical editor is assigned the window id 1
and is inserted into the Object List (see Figure 16(a)). A data graph maintains a linked list
‘Node List’ to hold the nodes (e.g., queues, sources, and sinks; a node is also an object that
may be inserted in the Object List) created in the canvas area of the graphical editor.
Suppose that the user selects the queue item in the node selection area (see Figure 3) and
places the queue instance named q1 in the canvas area. The callback function of the main
C1 void Queue::CreatePDB() {
C2
if(windowId !=-1) return;
C3
windowId = GetWindowId();
C4
SendL1("DATASET { %d, Queue Parameters;", windowId);
C5
SendL1("ENTRY (Server No., 1)");
C6
SendL1("RADIO (Scheduling Policy, <FIFO, NPP, PP>, FIFO)");
C7
SendL1("BUTTON (Job-Type)");
C8
SendL1("BUTTON (Output)");
C9
SendL1("}");
C10 }
Figure 13. The CreatePDB function
206
S1
S2
S3
S4
S5
S6
S7
S8
S9
S10
S11
S12
S13
S14
S15
S16
S17
S18
S19
S20
S21
S22
S23
Y.-B. LIN AND D. DALY
void DataSet::ModifyPDB(String command) {
Parameter *par = parList->GetParameter(command);
switch(par->type) {
case INT_PAR:
*((int*) par->ptr) = GetIntValue(command);
break;
case FLOAT_PAR:
*((double*) par->ptr) = GetFloatValue(command);
break;
case STRING_PAR:
*((String*) par->ptr) = GetStringValue(command); break;
case RADIO_PAR:
*((RadioDataItem*) par->ptr)->SetValue(GetButtonValue(command));
break;
case CHECK_PAR:
*((CheckDataItem*) par->ptr->SetValue(GetButtonValue(command));
break;
case DATA_TABLE_PAR:
((DataTable *) par->ptr)->CreatePDB();
break;
case DATA_SET_PAR:
((DataSet *) par->ptr)->CreatePDB();
break;
case DATA_GRAPH_PAR:
((DataGraph *) par->ptr)->CreatePDB();
break;
default:
error(...);
};
}
Figure 14. The ModifyPDB function
graphical editor sends a string
create QUEUE q1
to the Command Generator at Layer 2 (see Figure 2). The Command Generator prepends the
window id of the main graphical editor and sends the string to Layer 2 (see, Figure 16(b)).
When Layer 2 receives the string, the Command Parser (see, Figure 2) interprets the command, and uses the window id to locate the corresponding Layer 2 object (i.e., the data
graph for the main graphical editor) in the Object List (see line L3 in Figure 15). Then
the ModifyPDB function of the object is invoked to carry out the Layer 1 command (see
line L4). In Figure 16(b), the data structure for q1 is created and inserted in the Node List
of the data graph. Then Layer 2 sends a message ‘success’ back to Layer 1 (see line L5;
the details are not given).
If the user clicks the mouse button on the q1 icon in the canvas area, then the main
graphical editor callback function sends a string
modify q1
to the Command Generator. Again, the Command Generator prepends the window id to
the string and sends the string to Layer 2. The data graph in the Object List at Layer 2 is
A FLEXIBLE GRAPHICAL USER INTERFACE
L0
L1
L2
L3
L4
L5
L6
207
notComplete = 1;
while(notComplete) {
ReceiveL1(command);
Object *object = objectList->GetObject(command);
object->ModifyPDB(command);
... /* house-keeping operations here */
}
Figure 15. The Layer 2 main loop
identified, and its ModifyPDB function is invoked to insert the Queue Parameters data set
for q1 (i.e., the ‘pdb’ box in Figure 16(c)) into the Object List. The data set is assigned a
window id 2. Then the CreatePDB function for the data set (see Figure 13) is invoked.
The strings shown in Figure 12 are sent to Layer 1. These strings are parsed by Command
Parser at Layer 1 (see, Figure 2) based on the following production rules (the bold font
characters represent non-terminals, and the roman font characters represent terminals or
tokens in a production rule):
DataSet ⇒ DATASET { Integer, String; DataItems }
DataItems ⇒ DataItem DataItems | DataItem
DataItem ⇒ ENTRY | RADIO | CHECK | BUTTON
ENTRY ⇒ ENTRY (String, String)
RADIO ⇒ RADIO (String, <RadioList>, String)
RadioList ⇒ String, RadioList | String
CHECK ⇒ CHECK (String, <CheckList>)
CheckList ⇒ String, String; CheckList | String, String
BUTTON ⇒ BUTTON (String)
The production rules for ENTRY, RADIO, CHECK and BUTTON are associated with
actions which create the corresponding graphical widgets. The action for the DataSet rule
creates the PDB as shown in Figure 5(b). Note that Layer 1 does not have knowledge
about the PDB to be created. Instead, the information is provided by Layer 2. This feature,
together with the fact that all callback functions for the graphical widgets are simple ‘print’
commands, make it easy to replace the implementation of Layer 1 (and thus the application
extensibility goal is achieved).
Suppose that the user accesses the Queue Parameters PDB for q1 and set the Server No.
parameter to 3. Then a string
2 ‘Server No.’ 3
is sent to Layer 2. The data set with window id 2 in the Object List is identified. The data
set’s ModifyPDB function (see Figure 14) is invoked to interpret the sub-string
‘Server No.’ 3
The Server No. parameter in parList is identified (see line S2, Figure 14). Since this parameter is an integer, line S5 is executed and the number 3 is extracted by the GetIntValue
function and is assigned to the variable num.
208
Y.-B. LIN AND D. DALY
Figure 16. The interactions between Layer 1 and Layer 2
Figure 17 illustrates the canvas area and the Object List when two queue nodes and three
PDBs are active. If the user presses the OK button of q2’s Queue Parameters PDB, then
the PDB disappears, and Layer 1 sends a message
3 quit
to Layer 2. When this message is received, the corresponding data set is deleted from the
Object List (see Figure 18(a)). If the user clicks on q2 icon in the canvas area again, then
the data set is inserted back to the Object List with a new window id 5 (see Figure 18(b)),
and the window information is sent to Layer 1 to generate the PDB. If the ‘quit’ command
is for the main graphic editor, then the variable notComplete in the Layer 2 main loop
(see Figure 15) is set to 0, and the simulation environment exits.
In summary, GUI/PM provides a simple and consistent interaction protocol between
Layer 1 and Layer 2. With the Object List structure, GUI/PM allows multiple active PDBs.
That is, the user may modify q1’s PDB without closing q2’s PDB. This feature is achieved
by a very simple execution control (see, Figure 15). In some simulation packages, such as
Q+, the current PDB must be closed before the user modifies a new PDB.
6.
SUBNETWORK
Model reusability is usually provided by a hierarchical structure of subnetworks. Most
simulation packages1,2,3 provide basic operations for subnetworks (other packages such as
A FLEXIBLE GRAPHICAL USER INTERFACE
209
Figure 17. The interactions between Layer 1 and Layer 2 (Cont.)
PRISM11 do not support subnetworks):
1. A subnetwork can be built by basic cut and paste operations.
2. A model can possess submodels to any degree of nesting.
However, the following important issues are not well-addressed:
1. Interactions to the world outside the subnetwork
2. Input parameter setup
3. Output parameter measurement
This section describes how GUI/PM addresses these issues.
We demonstrate the GUI/PM subnetwork concept by an example in Figure 19. In GUI/PM,
a subnetwork node is created by selecting the subnet item in the node selection area (Figure 19(a)). If the subnetwork node is clicked twice by the right button, then a new graphical
editor is brought up (Figure 19(b)), which can be used to construct the subnetwork graphically. Two node types I (Input Port) and O (Output Port) are introduced in a subnetwork
graphical editor (to be discussed later). Note that there is also a subnetwork item in this
graphical editor which allows the user to build subnetworks within a subnetwork.
6.1.
The I/O Relationship to the Outside World
In most simulation packages (including GUI/PM), the I/O relationship of a subnetwork is
inherited from that of the basic modeling object. The ‘port’ concept is usually used to provide
information hiding for communications among nodes or subnetworks. Some simulation
packages (e.g., Q+) do not have the port concept, and the user needs to directly access a
node inside the subnetwork to connect a node outside the subnetwork. This I/O facility does
not provide information hiding, and the user may easily make a wrong connection.
210
Y.-B. LIN AND D. DALY
Figure 18. Deleting and adding elements to the object list
Opnet provides the port facility. The ports of a subnetwork are not shown graphically
(in other words, the graphic facility does not provide enough information to the user to
understand the I/O interface of a subnetwork). Connecting a port in the subnetwork to a
port in the outside world is a two-step operation. The user first selects the node from the
node table of the subnetwork. Then Opnet brings up the port table of the selected node. The
user selects the port and then makes the connection. Again, this approach does not provide
information hiding because the user may access irrelevant information and make mistakes.
In ObjectTime, the user does not need to access the internals of the subnetwork to make
a connection. A set of ports can be created for a subnetwork. These ports are mapped to
the ports of nodes inside the subnetwork (the names of these subnetwork ports may be
different from the mapped ports to give better logical meaning). The ports for a subnetwork
are shown graphically in the subnetwork icon. This approach provides information hiding.
However, if a subnetwork has a large number of ports, then the graphical representations
of these ports are not distinguishable. An interface layer must be built by the user through
a non-trivial way.
The subnetwork I/O facility of GUI/PM is similar to that of ObjectTime. Furthermore, a
port table is associated with every subnetwork, which allows the user to make connections by
selecting a port from a large number of ports in a subnetwork. (In ObjectTime, programming
effort is required to build an interface for a subnetwork to accommodate a large number of
ports.) Figure 19(c)–(f) illustrate how to establish the I/O relationship between a subnetwork
and the outside world in GUI/PM.
In Figure 19(d), a node representing an input port of the subnetwork is created by selecting
the input port item. When this node is placed in the canvas area of the subnetwork graphical
editor, an input port (with the same name as the created input port node) is also created
and attached to the Subnet:1 node in the canvas area of the main graphical editor (see
Figure 19(c)).
Like ObjectTime, GUI/PM allows the user to create ports for the subnetwork node using
the normal port operations in Figure 19(c). In this case, a port node is automatically created
and placed in the left corner of the canvas area of the subnetwork graphical editor. This
A FLEXIBLE GRAPHICAL USER INTERFACE
211
Figure 19. Constructing a subnet
feature allows the top-down network design.
The subnetwork may be reused for different purpose where the I/O relationship must
be redefined. In GUI/PM, the subnetwork ports can be easily added/deleted/renamed by
using the port operations either in the Port menu of the parent graphical editor (and the
operations for a subnetwork node are exactly the same as the operations for a basic node)
or in the Option menu of the subnetwork graphical editor.
212
Y.-B. LIN AND D. DALY
Figure 20. Creating PDBs for subnetwork
6.2.
Input Parameter Setup
In most simulation packages,1,2,3,11 setting up the parameters for a subnetwork requires
getting at the internals of the subnetwork and accessing the parameters node-by-node. This
approach has two disadvantages. First, setting up the parameters by accessing several nodes
distributed in a subnetwork is a tedious process, especially when an accessed node itself is a
subnetwork. Second, no information hiding is provided. The user is responsible for selecting
the right parameters to be set up. In most cases, only a small number of parameters need
to be set up for a subnetwork. The user may accidentally access and modify the irrelevant
subnetwork parameters.
In GUI/PM, a PDB which includes all the parameters that need to be set up for a
subnetwork is associated with each subnetwork instance. A parameter of a node inside
a subnetwork can be added to or deleted from the subnetwork’s PDB by the parameter
operations in the Option pulldown menu of the subnetwork’s graphical editor. (This is done
during the run-time, no re-compilation is required.) For example, to include the Server No.
parameter of Queue:1 as a parameter of Subnet:1 in Figure 19(f), we first select the add
parameter operation in the Option pulldown menu. Then bring up the PDB of Queue:1
and select the Server No. parameter (by hitting the return key in the text area). A dialog
box will pop up, which can be used to rename the parameter to be included in Subnet:1’s
PDB.
In Figure 20(a), Server No. and Job-Type of Queue:1, and Job-Type of Queue:2 are in-
A FLEXIBLE GRAPHICAL USER INTERFACE
213
cluded in Subnet:1’s PDB and are renamed to Server No.(Q1), Class(Q1), and Class(Q2),
respectively. Note that there is a predefined Output parameter (a button) in every subnetwork’s PDB (to be described later). Modifying the value of server no.(Q1) in Subnet:1’s
PDB has the same effort as modifying Server No. in Queue:1’s PDB, and vice versa.
Similarly, pressing the Class(Q2) button is equivalent to pressing the Job-Type button in
Queue:2’s PDB.
Adding a new parameter such as Server No.(Q1) to Subnet:1’s PDB is implemented as
follows. When the user selects the add parameter operation from the Option pulldown
menu of Subnet:1’s graphical editor, the window id of the graphical editor, g id, and the
operation name add parameter are saved in a message buffer. After Server No. of Queue:1
is selected and renamed, the window id of Queue:1’s PDB, n id, and two strings
Server No. and Server No.(Q1)
are also saved in the message buffer. Layer 1 only uses the string Server No.(Q1) and
the type of the Server No. parameter (which is an integer entry) to modify the graphical
appearance of Subnet:1’s PDB. A message
g id add parameter ‘Server No.(Q1)’ n id ‘Server No.’
is sent from Layer 1 to Layer 2. Layer 2 uses g id to search the Subnet:1 data set D1 in
the Object List. Similarly, n id is used to search D2, the data set for Queue:1.
The add parameter command directs Layer 2 to execute a procedure which does the
following:
1. A new parameter, p, of type PTR PAR is added to D1. The name field of p is assigned
the string Server No.(Q1).
2. The string Server No. is used to search the Server No. parameter in D2. The pointer
of this parameter, y, is assigned to the ptr field of the parameter p in D1.
The relationship between D1, D2, and D3 (the data set for Queue:2) is given in Figure 20(b). Note that the type field in D1’s parList and both the type and ptr fields in
the parLists of D2 and D3 are not shown in the figure. Suppose that the user assigns
the value 12 to Server No.(Q1) in Subnet:1’s PDB. The corresponding callback function
simply sends a string to the Command Generator, which is prepended the window id ‘wid’
for the Subnet:1 PDB to form the message
wid modify ‘Server No.(Q1)’ 12
This message is sent to Layer 2. When Layer 2 receives the message, it uses wid to find
D1. Then the string Server No.(Q1) is used to locate the corresponding parameter p in D1.
Since p is of type PTR PAR, the ptr field of p is used to locate the Server No. parameter
in D2, and the corresponding variable num is assigned the value 12.
The parameter deletion operation merits further discussion. Consider the Network hierarchy in Figure 21(a). The parLists of the data sets for Subnet1, Subnet2, and Node1 are
given in Figure 21(b). In the figure, parameterX, parameterY, parameterC, and parameterD
are of type PTR PAR. Suppose that parameterC of Subnet2 is deleted. This deletion operation propagates to Subnet1, and parameterY is automatically deleted (see Figure 21(c)).
If the subnetwork is reused for different purpose, then the PDB can be easily modified
by using the add parameter and delete parameter operations in a subnetwork graphical
214
Y.-B. LIN AND D. DALY
Figure 21. Deleting parameters from a subnetwork PDB
editor. Another example of PDB is given in Figure 20(c), and the corresponding data set
for the subnetwork, D4, and its relationship to D2 and D3 are given in Figure 20(d).
The parameter setup procedure for subnetwork is exactly the same as the procedure for
a basic node type. Furthermore, the same subnetwork structure can be reused by assigning
different sets of input parameters. Creating PDBs for a subnetwork is done by the parameter
operations in the Option pulldown menu of a subnetwork graphic editor.
A FLEXIBLE GRAPHICAL USER INTERFACE
215
Figure 22. Monitoring the output statistics for a packet
6.3.
Output Measurement
Often it is necessary to collect output statistics, such as the response time, for a subnetwork. In most simulation packages, tedious programming effort is required to measure
subnetwork-wide output statistics. In GUI/PM, some important output statistics for a subnetwork are measured automatically. Let us use the ‘response time’ for a subnetwork (the
time that a packet or job stays in the subnetwork) as an example to demonstrate the idea.
Consider Figure 22. A packet p1 is generated at the main network, which enters Subnet1 at
timestamp 10. Then it enters Subnet2 at timestamp 20. At timestamp 30, it leaves Subnet2,
and at timestamp 40, it leaves Subnet1. A simple approach is used in GUI/PM to compute
the response time for p1.
A Stack data structure is associated with every packet. Every subnetwork has two monitor components. The InMonitor monitors the packets that enter the subnetwork, and The
OutMonitor monitors the packets that leave the subnetwork. In Figure 22 IM 1, OM 1 and
IM2, OM2 represent the InMonitor and OutMonitor for Subnet1 and Subnet2, respectively.
When p1 enters Subnet1, IM1 pushes a timestamp 10 into p1’s stack. When p1 enters Subnet2, IM2 pushes the timestamp 20 into p1’s stack. When p1 leaves Subnet2 at timestamp
30, OM2 pops the top element of p1’s stack which is the timestamp 20. Then OM2 computes the response time of p1 as 30 − 20 = 10. When p1 leaves Subnet1 at timestamp
40, OM1 pops the timestamp 10, and computes the response time as 40 − 10 = 30. The
InMonitor and OutMonitor components can be easily modified to compute other output
statistics such as throughput.
To conclude, GUI/PM provides a systematic way to compute the output statistics for
subnetworks, which is achieved by a simple yet efficient stack approach. In most simulation
packages users are required to do tedious programming before they can measure subsystem
output statistics.
216
Y.-B. LIN AND D. DALY
7.
CONCLUSIONS
In this article we have proposed a flexible graphical user interface for performance modeling
(GUI/PM) to achieve three design goals.
To achieve user friendliness, in addition to many user-friendly features provided in the
traditional GUI design, parameter setup for models in GUI/PM is conveniently done through
parameter dialog boxes (PDBs). When the user creates a new node type, the corresponding
PDBs are automatically generated by GUI/PM. No user programming effort is required to
produce PDBs.
To accommodate application extensibility, a two-layer structure is used in GUI/PM.
Layer 1 is responsible for generating graphical layouts for the GUI, and acts simply as
a filter between the user and Layer 2 (the graph application). Layer 1 and Layer 2 are
loosely coupled, and Layer 1 can be easily replaced to accommodate different simulation
applications.
To promote model reusability, subnetworks in GUI/PM use PDBs to simplify the parameter setup procedure. The port concept is used to define the I/O relationship between
a subnetwork and the outside world. Subnetwork-wide output measures are provided by a
simple stack mechanism. Subnetwork is a first class citizen in GUI/PM. All operations for
basic node types also apply to subnetworks. In addition, extra operations are provided to
support subnetwork features not found in the basic node types. Thus, a subnetwork node can
be viewed as a basic node type. If the user is not interested in the internals of a subnetwork,
he may treat a subnetwork as a normal node and set up the parameters for the subnetwork
through PDB.
ACKNOWLEDGMENTS
Layer 1 of COPS GUI was implemented by J. Geigel. The anonymous reviewers and the
COPS members K. Kant, V. Mak and D. Mok provided valuable comments.
REFERENCES
1. Northern Telecom Ltd, ObjectTime Supplementary User Guide, 1992.
2. C. A. Funka-Lea, T. D. Kontogiorgos, R. J. T. Morris and L. D. Rubin, ‘Interactive visual modeling for
performance’, IEEE Software, 8(5), 58–67 (1991).
3. MIL 3, Inc., Opnet Tool Operations Manual, 1991.
4. Y.-B. Lin and V. K. Mak, ‘Eliminating the boundary effect of a large-scale personal communication service
network simulation’, ACM Transactions on Modeling and Computer Simulation, 4(2), 165–190 (1994).
5. D. Daly, K. Kant, Y.-B. Lin, V. Mak and D. Mok, ‘COPS: a computer operations perforamnce simulation
system’, Second Bellcore Symposium on Performance Modeling, Bellcore, 1992, pp. 165–174.
6. J. K. Ousterhout, An Introduction to Tcl and Tk, Addison-Wesley, Reading, MA, 1992.
7. J. M. Vlissides and M. A. Linton, ‘Unidraw: a framework for building domin-specific graphical editors,
ACM Transactions on Information Systems, 8(3), 237–268 (1990).
8. Hewlett Packard, InterViews Plus Programmer’s Guide, 1992.
9. F. Cohen, R. B. Gowin, K. Kvidahi, D. Ruddock and E. L. Sigman, ‘Application programming’s guide to
Penguin 1.0’, Technical Report, Bellcore, 1992.
10. J. Geigel, ‘The COPS GUI – a programmer’s guide’, Technical Report, Bellcore, 1993.
11. P. W. Vaughan and D. E. Newton, ‘PRISM: an object-oriented system modeling toolkit, International
Journal in Computer Simulation, 4(2), 209–234 (1993).