Aller au contenu principal

Create, read and modify a list, using a Loop determined by length of content

PRESENTATION

This tutorial is an introduction to the creation of loops and the use of Complex Types in Designer. You will be guided through the process of extracting the content of a list, using the Trigger Activity element. Then, you will learn how to modify the list, by adding or removing lines or modifying the content of the lines.

Prerequisites

Skills that you will acquire

On Designer:

  • use a Complex Data Type and some vector's operations from C++,
  • model a Loop via the utilisation of Trigger Activities.

On Virtual Bench:

  • define a mapping with a Complex Data Type as parameter.

Duration

2h30

CREATE THE MODEL

  • Create a model called "LoopTest"
  • Create a new project called "LoopProject"
  • Create a service called "LoopV1"
  • Create a life phase Standard use in "LoopV1"

Create a Complex Data Type

In the Type Diagram, add two New DataTypes:

  • UserDescriptionType: with the Attributes name, surname and information. All three have Type: TextType and Multiplicity: One
  • UserListType: with the Attribute UserList. Type: UserDescriptionType and Multiplicity: Many
DataTypes

Create the Use Cases

In the Use Case Diagram, create:

  • a New actor called "User",
  • new use cases called "Inform about members" (where the content of the list is read and extracted during the loop) and "Modify the list"

Create the User Stories

In Modify the list, create four New User Stories: "the server receives the list", "the user adds a new member", "the user removes a member" and "the user modifies the information in the list".

In Inform about members, create three New User Stories: "the user requests information about members", "the server warns the member" and "the user has all information".

Complete "the server receives the list"

  • Drag&Drop a New State. Select FirstState, click on OK and rename the state after creation (in Inactive),
  • Drag&Drop a New State, Click on New State, drag&drop a New State (rename it "Active"), return to the server receives the list, and repeat, selecting "Active",
  • Create the Variables: ListOfUsers (UserListType) and TotalNumberOfUsers (IntegerType, default value = 0),
  • Create New Message from Environment to LoopBB, click on Create a new flow:
    • Drag&Drop a New Interface: I_receive_the_member_list,
    • Drag&Drop a New Flow in the Interface: receive_the_member_list (Data: list, UserListType),
  • Create Internal Activity: "integrate_the_list"
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
ListOfUsers = receive_the_member_list_list;
TotalNumberOfUsers = ListOfUsers.UserList.size();
the server receives the list

Complete "the user requests information about members"

This User Story is the initialization of the loop.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create a New Message from User to LoopBB:
    • Interface: I_request_information_about_members,
    • Flow: request_information_about_members,
  • Create Internal Activity: "select_first_member"
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
// start of loop

UserName = ListOfUsers.UserList[0].name;
UserSurname = ListOfUsers.UserList[0].surname;
UserInformation = ListOfUsers.UserList[0].information;
  • Create four New Variables: NumberOfMembersTreated (IntegerType, default value = 0), UserName, UserSurname and UserInformation (all three TextType),
  • Create a New Message from Lifeline to Environment:
    • Interface: I_give_information,
    • Flow: give_information, add three Data, all TextType: member_name (Value: UserName), member_surname (Value: UserSurname) and member_information (Value: UserInformation),
  • Create Internal Activity: "select_next_member"
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
// next iteration

NumberOfMembersTreated = NumberOfMembersTreated + 1;

if (NumberOfMembersTreated < TotalNumberOfUsers) //check that we are not off the list
{
UserName = ListOfUsers.UserList[NumberOfMembersTreated].name;
UserSurname = ListOfUsers.UserList[NumberOfMembersTreated].surname;
UserInformation = ListOfUsers.UserList[NumberOfMembersTreated].information;
}
the user requests information about members

Complete "the server warns the member"

This User Story is the iterative part of the loop.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create a New Trigger Activity and select "select_next_member",
  • Create a Guard Condition (Constraint: NumberOfMembersTreated is strictly less than TotalNumberOfUsers),
  • Create a New Message from Lifeline to Environment, select give_information. The details are the same as for give_information in "the user requests information about members",
  • Create a new Internal Activity, select "select_next_member".
the server warns the member

Complete "the user has all information"

This User Story is the end part of the loop.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create a New Trigger Activity and select "select_next_member",
  • Create a Guard Condition (Constraint: NumberOfMembersTreated is equal to TotalNumberOfUsers),
  • Create a new Internal Activity, named "end_of_member_list"
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
// end of loop

NumberOfMembersTreated = 0;
the user has all information

Complete "the user adds a new member"

This User Story shows you how to add a new line in a vector.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create three New Variables TextType: NewName, NewSurname, NewInformation,
  • Create a New Message from User to Lifeline:
    • Interface: I_modify_the_list,
    • Flow: add_new_member_to_list (three Data TextType: newname, newsurname, newinformation),
  • Create Internal Activity: "add_new_member",
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
UserDescriptionType myNewLign; // define a temporary lign

myNewLign.name = add_new_member_to_list_newname ;
myNewLign.surname = add_new_member_to_list_newsurname ;
myNewLign.information = add_new_member_to_list_newinformation ;

ListOfUsers.UserList.push_back(myNewLign); // push the temporary lign
TotalNumberOfUsers = TotalNumberOfUsers + 1; // increase the list size
the user adds a new member

Complete "the user removes a member"

This User Story shows you how to remove a line in a vector.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create two New Variables TextType: TargetName and TargetSurname,
  • Create a New Message from User to LoopBB:
    • Reuse the interface: I_modify_the_list,
    • Flow: remove_member_to_list (two Data TextType: targetname, targetsurname),
  • Create Internal Activity: "remove_member",
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
TargetName = remove_member_to_list_targetname ;
TargetSurname = remove_member_to_list_targetsurname ;

if (ListOfUsers.UserList.size() > 0) //this line is to ensure the construction of the list
{
for (int i=0; i<ListOfUsers.UserList.size(); i++)
{
if (ListOfUsers.UserList[i].name == TargetName)
{
if (ListOfUsers.UserList[i].surname == TargetSurname)
{
ListOfUsers.UserList.erase(ListOfUsers.UserList.begin() + i);
TotalNumberOfUsers = TotalNumberOfUsers - 1;
}
}
}
}
the user removes a member

Complete "the user modifies the information in the list"

This User Story shows you how to modify the line content in a vector.

  • Drag&Drop a New State, select "Active" and click on OK,
  • Create three New Variables TextType: ModifName, ModifSurname and ModifInformation,
  • Create a New Message from User to LoopBB:
    • Reuse the interface: I_modify_the_list,
    • Flow: modify_the_information (five Data TextType: modifname, modifsurname, modifinformation, targetname, targetsurname),
  • Create Internal Activity: modify_the_information_in_the_list
    • Right-click on the new Internal Activity, click on Edit and Edit Body then copy the following text:
TargetName = modify_the_information_targetname ;
TargetSurname = modify_the_information_targetsurname ;
ModifName = modify_the_information_modifname ;
ModifSurname = modify_the_information_modifsurname ;
ModifInformation = modify_the_information_modifinformation ;

UserDescriptionType ModifLign;

ModifLign.name = ModifName ;
ModifLign.surname = ModifSurname ;
ModifLign.information = ModifInformation ;

if (ListOfUsers.UserList.size() > 0) //this line is to ensure the construction of the list
{
for (int i=0; i<ListOfUsers.UserList.size(); i++)
{
if (ListOfUsers.UserList[i].name == TargetName)
{
if (ListOfUsers.UserList[i].surname == TargetSurname)
{
ListOfUsers.UserList[i].name = ModifName;
ListOfUsers.UserList[i].surname = ModifSurname;
ListOfUsers.UserList[i].information = ModifInformation;
}
}
}
}
the user modifies the information in the list

Generate State Machine

remarque

If you have the community version of Designer (free version), please build the executable via Hub4Sys as shown on this page, else (pro version) continue this section of the tutorial.

Once this is done, return to each user story, right-click on the diagram and select Edit > Generate State Machine. Once it is done for every user story, click on the button Generate and build.

Once the Model is finished with no errors, click on your Project then on Export File XML.

SIMULATION MAPPING

For the simulation we will need three scenario context:

  • HMI (HMI context),
  • timeline (Timeline context).

Then, add a new scenario, and double-click on its name to open it.
In your scenario tab, add a new WebSocket.
Select the executable you’ve created before, you can name the new Websocket as you want, and press Ok.

Controllers

Timeline context

Now let’s map the flow "introduce_the_list". To do that, see the following steps:

  • select the timeline context and drag&drop four TimelineAction timeline, separated by at least two seconds each.

  • Click on the first TimelineAction timeline, change the parameter Start time to 0 and the Event type to Trigger.
    For the second, do the same but put the Start Time at 5s.

  • Configure the controller tab of the first TimelineAction timeline and Trigger a controller for the flow "receive_the_member_list".

  • Check the lines list and UserList. For UserList, choose the number of members you desire by selecting the field and using the Up or Down arrow keys of the keyboard to increment or decrement the number of members (for this example we will say you chose three).

mapping_receive_the_member_list
  • Fill the lines of list as you wish, the picture below is an example:
fill UserList
  • Click on the button Edit, then save.

  • For the second TimelineAction, add a controller for the flow "add_new_member_to_list", create a new name, surname, and the information of this new member.

  • For the third TimelineAction, add a controller for the flow "modify_the_information", write in the cases targetname and targetsurname, the name and surname corresponding to the member you wish to modify.
    In modifname, modifsurname and modifinformation, write the information you want to replace the current ones with.

mapping_modify_the_information
  • For the fourth TimelineAction, add a mapping for the flow "remove_member_to_list", write in the cases targetname and targetsurname the name and surname corresponding to the member you wish to remove.
mapping_remove_member_to_list

HMI context

We will prepare a controller for the flow "request_information_about_members" :

  • go to the HMI context.
  • drag&drop the Button element (change its parameter buttonLabel to Search Information).
  • Right click on the button > Controllers > Trigger a controller.
  • Configure the controller for the flow "request_information_about_members".
mapping_request_information_about_members
  • Drag&Drop three Text elements, change their names to "Member Name", "Member Surname" and "Member Information".

  • For the first one, configure a controller to receive the flow "give_information" (Update by a controller).

  • Check the button for the trigger "Add new line" and the "Param" Text line under it.

  • Change constant to variable.

  • Click on the "Choose variable" button and select the flow parameter "member_name". Click on Ok, then Save.

  • For the second and third Text element, create two more mappings for the same flow "give_information" with the same trigger, but select "member_surname" and "member_information" instead.

Run your scenario

Once every step was followed, pass in Run mode.
Clicking on the Button element will result in the following images:

After the first Timeline action:

member_list_1

After the second Timeline action:

member_list_2

After the fourth Timeline action:

member_list_3