Action Examples

This section exemplifies the usage of the different categories of built-in functions, given by the FSM action language.

These action examples are also used to show, how the different built-in functions can be nested to create complex action statements. Like other C/C++ functions, MLDesigner FSM built-in-functions can be nested in such a way, that a function parameter of a specific data type can be set by another function, which returns a value of that data type.

In connection with data structures, nesting of FSM built-in functions is only working, if the data structure, returned by the inner function, is compatible to the data structure expected by the parameter of the outer function. For instance, it is not possible to set a data structure field of type Root.Address.IPAddress with a data structure of type Root.FloatVector. Such action statements are indeed compilable but lead to run-time errors!

The action examples are based on a FSM model with the following interface:

Type of interface element Name Type
input port PacketInput Root.NetworkProtocol.TCPProtocol
output port PacketOutput Root.NetworkProtocol.TCPProtocol
output port IntOutput Root.Integer
output port FloatOutput Root.Float
output port StringOutput Root.String
output port EnumOutput Root.ENUM.Boolean
memory PacketMemory Root.NetworkProtocol.TCPProtocol
memory IntMemory Root.Integer
memory FloatMemory Root.Float
memory StringMemory Root.String
memory EnumMemory Root.ENUM.Boolean
memory VectorOfPacketsMemory Root.Vector.VectorOfPackets
memory IntVectorMemory Root.IntVector
memory FloatVectorMemory Root.FloatVector
memory ListOfPacketsMemory Root.List
event PacketEvent Root.NetworkProtocol.TCPProtocol
event IntEvent Root.Integer
parameter IntParameter int
parameter FloatParameter float
parameter EnumParameter Root.ENUM.Boolean

Base Structures

//
// for-loop structure
//
WriteMemory(StringMemory,"Byte");
for (IntMemory = 1; (int)IntMemory <= 4; IncMemory(IntMemory))
{
 InsertFieldDS(SelectFieldDS(PacketMemory, "SourceIP"),
               ReadStringMemory(StringMemory) << (int)IntMemory,
               IntParameter + (int)IntMemory);
 InsertFieldDS(SelectFieldDS(PacketMemory, "DestIP"),
               ReadStringMemory(StringMemory) << (int)IntMemory, 0);
}

//
// while-loop structure
//
IntMemory = 0;
while ((int)IntMemory < (int)LengthOfVector(IntVectorMemory))
{
 SetElementIntVector(IntVectorMemory, (int)IntMemory,
                     (int)IntMemory * (int)IntMemory);
 IncMemory(IntMemory);
}

//
// do-while-loop structure
//
IntMemory = 0;
do
{
 Enqueue(ListOfPacketsMemory, PacketMemory, 0, (int)IntMemory);
 InsertFieldDS(PacketMemory, "DestPort", (int)IntMemory);
 IntMemory = (int)IntMemory + 1;
}
while ((int)IntMemory <= 3);

//
// if-else structure
//
if ((int)SelectFieldDS(PacketMemory, "SourcePort") < (int)IntMemory)
{
 InsertFieldDS(PacketMemory, "SourcePort", (int)IntMemory);
 IntToEnum(EnumMemory, 0);
}
else
{
 InsertFieldDS(PacketMemory, "SourcePort", IntParameter);
 IntToEnum(EnumMemory, 1);
}

//
// switch structure
//
switch (IntParameter)
{
case 0:
 InsertFieldDS(PacketMemory, "SourcePort", 10);
 break;
case 1:
 InsertFieldDS(PacketMemory, "SourcePort", 20);
 break;
default:
 InsertFieldDS(PacketMemory, "SourcePort", 0);
 break;
}

Composite Data Structure Handling

InsertFieldDS(PacketMemory, "SourcePort", DSToInt(IntMemory)); InsertFieldDS(PacketMemory, "DestPort", (int)IntMemory + 10);
InsertFieldDS(SelectFieldDS(PacketMemory, "SourceIP"), "Byte1", IntParameter);
InsertFieldDS(SelectFieldDS(PacketMemory, "DestIP"), "Byte2", 162);
InsertFieldDS(PacketMemory, "Name", DSToString(StringMemory));
WriteMemory(StringMemory, DSToString(SelectFieldDS(PacketMemory, "Name")));
IntMemory = SelectFieldDS(SelectFieldDS(PacketMemory, "DestIP"), "Byte4");

Enumeration Data Structure Handling

IntMemory = EnumToInt(EnumMemory); InsertFieldDS(PacketMemory, "SourcePort", EnumToInt(EnumParameter));
WriteMemory(StringMemory, EnumToString(EnumMemory));
InsertFieldDS(PacketMemory, "Name", EnumToString(EnumParameter));
IntToEnum(EnumMemory, ((int)IntMemory + 1) % 2);
StringToEnum(EnumMemory, "TRUE");

Vector Data Structure Handling

ChangeLengthVector(VectorOfPacketsMemory, IntParameter); WriteMemory(StringMemory, "Packet");
for (IntMemory = 0; (int)IntMemory < IntParameter; IncMemory(IntMemory))
{
  InsertFieldDS(PacketMemory, "Name",
                ReadStringMemory(StringMemory) << (int)IntMemory);
  SetElementVector(VectorOfPacketsMemory, (int)IntMemory, PacketMemory);
}
if (LengthOfVector(VectorOfPacketsMemory) > 10)
{
  PacketMemory = AccessElementVector(VectorOfPacketsMemory, 10);
  RemoveElementVector(VectorOfPacketsMemory, 10);
}
IntMemory = 0;
while ((int)IntMemory < (int)LengthOfVector(FloatVectorMemory) - 1)
{
  FloatMemory = AccessElementFloatVector(FloatVectorMemory,
                                         (int)IntMemory + 1);
  if ((double)FloatMemory < FloatParameter)
    FloatMemory = FloatParameter;
  SetElementFloatVector(FloatVectorMemory, (int)IntMemory,
                        (double)FloatMemory);
  IncMemory(IntMemory);
}
RemoveElementFloatVector(FloatVectorMemory,
LengthOfVector(FloatVectorMemory) - 1);

Memory Access

ResetMemory(IntMemory);

while ((int)IntMemory > 2)
  DecMemory(IntMemory);

do
  IncMemory(IntMemory);
while ((int)IntMemory < 4);

InsertFieldDS(PacketMemory, "SourcePort", ReadMemory(IntMemory));
InsertFieldDS(PacketMemory, "SourcePort", ReadIntMemory(IntMemory));
InsertFieldDS(PacketMemory, "SourcePort", (int)IntMemory);
InsertFieldDS(PacketMemory, "SourcePort", IntMemory);
WriteMemory(IntMemory, IntParameter + 10);

Port Handling

if (DataNew(PacketInput))
{
  PacketMemory = ReadNewInput(PacketInput);
  StringToEnum(EnumMemory, "TRUE");
}
else
{
  PacketMemory = ReadBufferedInput(PacketInput);
  StringToEnum(EnumMemory, "FALSE");
}
WriteOutput(FloatOutput, e() + pi());
WriteOutput(IntOutput, (int)SelectFieldDS(PacketMemory, "SourcePort"));
WriteOutput(PacketOutput, PacketMemory);
WriteOutput(StringOutput, "Hello World!");
WriteOutput(EnumOutput, EnumMemory);

Special Event Handling

PacketMemory = ReadCurrentEvent(PacketEvent); InsertFieldDS(PacketMemory, "Name", StringMemory);
ScheduleEvent(PacketEvent, FloatParameter, PacketMemory, 0);
if (EventIsScheduled(IntEvent, (int)IntMemory))
{
  FloatMemory = EventResidualTime(IntEvent, (int)IntMemory);
  CancelEvent(IntEvent, (int)IntMemory);
  IncMemory(IntMemory);
  ScheduleEvent(IntEvent, (double)FloatMemory, (int)IntMemory);
}
else
{
  IntMemory = IntParameter;
  ScheduleEvent(IntEvent, ExpRangen(FloatParameter), (int)IntMemory);
}

Queue Operations

ClearQueue(ListOfPacketsMemory); InitQueue(ListOfPacketsMemory, 10);
for (IntMemory = 0; (int)IntMemory < 2; IncMemory(IntMemory))
{
  InsertFieldDS(PacketMemory, "SourcePort", IntMemory);
  Enqueue(ListOfPacketsMemory, PacketMemory, 0, (int)IntMemory);
}
if (QueueCheck(ListOfPacketsMemory, 0))
{
  PacketMemory = Dequeue(ListOfPacketsMemory, 0);
  StringToEnum(EnumMemory, "TRUE");
}
else if (QueueLength(ListOfPacketsMemory) > 0)
{
  PacketMemory = PeekQueue(ListOfPacketsMemory, 0);
  InsertFieldDS(PacketMemory, "DestPort", 10);
  PokeQueue(ListOfPacketsMemory, PacketMemory, 0);
}
RemoveElement(ListOfPacketsMemory, 0);

Number Generators

FloatMemory = TNow() + ExpRangen(FloatParameter) + e() * pi();
InsertFieldDS(PacketMemory, "DestPort",
              (int)BinomialRangen(IntParameter, 0.5));

Simulation Report Handling

InfoNumber("Current time stamp: ", TNow(), "");
InfoNumber("Current IntMemory value: ", (int)IntMemory, "");
if ((int)IntMemory > IntParameter)
{
  InfoString("Value is ok!");
  DecMemory(IntMemory);
}
else if ((int)IntMemory == IntParameter)
{
  WarningString("Value has reached threshold!");
  IncMemory(IntMemory);
}
else
{
  ErrorString("Value is below threshold!");
}