Part IX: Multiple Clients, Arrays, and Generate Statements
Michael Chen
August 29, 1996
Rewritten: H. Hildreth, 10-2-96
PART IX: MULTIPLE CLIENTS, ARRAYS AND GENERATE STATEMENTS
Objective: Change the model to accommodate multiple (> 2) users/clients
(described in Parts A and B below).
Also incorporate a means of determining whether or not multiple users/clients
are working on (contributing to) the same diagram (discussion) (described
in Part C below).
Rapide Concepts Introduced: Arrays and associated connection rules,
including "generate" statements where appropriate.
Note: The Rapide code was broken down into smaller pieces which must be
separately compiled IN ORDER. The compilation order and commands are
contained in the file: compile_script. "source"ing this file generates
the executable file: lrdc_exe. Executing lrdc_exe generates lrdc_exe.log.
For reference, compile_script contains:
rpdc -L resource.rpd
rpdc -L uil-col.rpd
rpdc -L client.rpd
rpdc -L server.rpd
rpdc -L ail.rpd
rpdc -L -M lrdc_arch -o lrdc_exe lrdc.rpd
Procedure: For this example we describe important differences between
this and earlier versions. Part-9 files are addressed separately; i.e.,
ail.rpd is described in Part A, and lrdc.rpd is described in Part B.
Within Parts A and B, subparts A1 and B1 describe arrays, and subparts
A2 and B2 describe array connections. Within subparts A2 and B2, connections
without "generate" statements are describe in subpart a (i.e, A2a and B2a),
and connections with "generate" statements are described in subpart b (i.e.,
A2b and B2b).
PART A1: Arrays
Earlier version (Part 4):
architecture ail()
is
C1, C2 : Client is ClientArch();
S : Server is ServerArch();
New version (Part 9):
architecture ail_arch() for ail_interface
is
Clients : array [integer] of Client is (1..Num_Clients,
default is ClientArch());
S : Server is ServerArch();
PART A2: Array Connections
LHS = left-hand side
RHS = right-hand side
PART A2a: without "generate" statement
Earlier version (Part 7):
COL.IDA.start_belvedere() ||>
C.COL.IDA.start_belvedere();
New version (Part 9): Client ID is LHS parameter and RHS array index.
(?I in Integer) COL.IDA.start_belvedere(?I) ||>
Clients[?I].COL.IDA.start_belvedere();
PART A2b: with "generate" statement
Earlier version (Part 7):
(?U in URL_Type, ?A in Action_Type) C.Server_Request(?U, ?A) ||>
S.Server_Request(?U, ?A);
...
C.WebStartup ||> PB.WebStartup;
C.JavaStartup ||> PB.JavaStartup;
New version (Part 9): Client ID is RHS array index and LHS parameter.
for I : Integer in 1..Num_Clients generate
Clients[I].WebStartup ||> PB.WebStartup(I);
Clients[I].JavaStartup ||> PB.JavaStartup(I);
(?U in URL_Type, ?A in Action_Type, ?D in Diagram_ID)
Clients[I].Server_Request(?U, ?A, ?D) ||>
S.Server_Request(?U, ?A, ?D, I);
...
end generate;
NOTE: Generate statements are used when the generate-loop variable can
be used on the LHS of the connection rules. It may appear on the LHS and
not the RHS, or it may appear on the LHS only.
PART B1: Arrays
Earlier version (Part 7):
architecture lrdc_arch() is
UI : user_interface;
CO : concepts_of_operation_interface;
New version (Part 9):
architecture lrdc_arch() is
UI : array [integer] of user_interface is
(1..Num_Clients, default is New(user_interface));
CO : array [integer] of concepts_of_operation_interface is
(1..Num_Clients, default is New(concepts_of_operation_interface));
PART B2: Array Connections
PART B2a: without "generate" statement
Earlier version (Part 7):
AI.PB.HTMLPage ||> CO.PB_IN.HTMLPage;
New version (Part 9): Client ID is LHS parameter and RHS array index.
(?i in integer)AI.PB.HTMLPage(?i) ||> CO[?i].PB_IN.HTMLPage;
PART B2b: with "generate" statement
Earlier version (Part 7):
UI.UIL.start_java() ||> CO.UIL.start_java();
...
CO.COL.IDA.start_belvedere() ||>
AI.COL.IDA.start_belvedere();
...
CO.PB_OUT.WebStartup ||> UI.PB.WebStartup;
New version (Part 9): Client ID is array index on both LHS and RHS.
A very long generate statement!
for i:integer in 1..Num_Clients generate
UI[i].UIL.start_java() ||> CO[i].UIL.start_java();
...
CO[i].COL.IDA.start_belvedere() ||>
AI.COL.IDA.start_belvedere(i);
...
CO[i].PB_OUT.WebStartup ||> UI[i].PB.WebStartup;
...
end generate;
PART C: Adding Diagram ID's
Note: This section does not introduce new Rapide concepts. The
purpose of this section is to explain changes made in order to satisfy
the requirement that the Connection Manager notify
clients of changes made to diagrams by other clients.
In the JavaTools component, an integer representing a diagram id
is received everytime a user decides to Open_Inquiry_Diagram. This integer
is stored within JavaTools and is passed as a parameter to any events that
cause graph changes, such as Add_Node and Add_Edge:
behavior
diagram_number : var integer := 0;
begin
COL.IDA.list_inquiry_diagram ||> Request(List_Inquiry_Diagram, 0);;
(?D in Diagram_ID) COL.IDA.open_inquiry_diagram(?D) ||>
diagram_number := ?D;
Request(Open_Inquiry_Diagram, ?D);;
COL.IDA.add_node ||> Request(Add_Node, $diagram_number);;
COL.IDA.add_edge ||> Request(Add_Edge, $diagram_number);;
In the Connection Manager, the diagram id's of the clients are stored in an
array and when the Connection Manager receives notification of one client
performing an action, it scans the array to find other clients working on
the same diagram and sends graph updates to those clients:
behavior
DA : array [Integer] of Ref(Diagram_ID) is
(1..Num_Clients, default is Nil(Diagram_ID));
begin
(?A in Action_Type, ?D in Diagram_ID, ?I in Integer)
UpdateToConMan(?A, ?D, ?I) ||>
if ?A = Open_Inquiry_Diagram then
DA[?I] := ?D;
else
for J : Integer in 1..Num_Clients do
if not (J = ?I) And not (DA[J].Is_Nil()) then
if $(DA[J]) = ?D then
Notify(?A, ?D, J);
end if;
end if;
end for;
end if;;
end ConnectionManager;
[
Back to the Index |
Next |
Prev]