[TRW Logo]

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 A: ail.rpd

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 B: lrdc.rpd

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]

© 1996 TRW Inc. All rights reserved.