Writing Logic in FlexSim

Where to Get Help

Whenever you need help with what commands to use and how to use them, you can refer to the Commands documentation, which is accessible through FlexSim's Help menu. Refer to the FlexScript Class Reference for information about FlexScript classes.

FlexScript and C++ General Rules

Here are some general rules you will need to know when creating your own logic.

  • Language is case sensitive (A is not the same as a)
  • No specific format is required (free use of spaces, tabs and line returns is encouraged)
  • Text strings are usually entered between quotes. "mytext"
  • Parentheses follow a function call and commas separate the arguments of the function. moveobject(object1,object2);
  • The end of a line or function call will always end with a semi-colon
  • Parentheses can also be used freely to make associations in your math and logic statements.
  • Curly braces are used to define a block of statements.
  • To comment out the rest of a line use //
  • To comment out blocks of text use /* text */
  • Don't use spaces or special characters in name definitions (_ is ok).
  • Named variables and explicit values can be interchanged in writing expressions.

Variable Types

FlexSim uses various variable types. Some of the more common are listed here. Refer to the FlexScript Class Reference for the complete list of FlexScript classes.

Classes

Type Description
int integer number type
double double precision floating point number type
string text string
treenode reference to a FlexSim node
Variant a number, string, treenode or array
Array a collection of Variants
Object treenode with object data
Color rgba components of a color
Vec3 xyz components of a vector
Table a table of elements
List dynamic list of things used for synchronizing tasks and logic
var type inferred variable

For more information on how the treenode (or FlexSim node) type works, refer to the FlexSim tree structure.

Declaring and Setting Variables

The following are some examples of how to declare and set variables.


		int index = 1;
		double weight = 175.8;
		string category = "groceries";
		treenode nextObj = Model.find("Processor1");
		Variant cellValue = table[2][3];
		var value = 3;
		

Constructing Class Objects

The following are examples of how to use constructors.


		Color myColor = Color(1, 0, 0);   // Makes a red color
		object.location = Vec3(0, 0, 0);  // Sets the object's location to the origin
		

Math Operations

The following list show different math operations that can be performed on values.

Operation Floating Point Example (=solution) Integer Example (=solution)
+ 1.6+4.2 (=5.8) 2+3 (=5)
- 5.8-4.2 (=1.6) 5-2 (=3)
* 1.2 * 2.4 (=2.88) 3*4 (=12)
/ 6.0/4.0 (=1.5) 20/7 (=2)
% (integer mod) 34%7(=6)
Math.sqrt() Math.sqrt(5.3) (=2.3)
Math.pow() Math.pow(3.0,2.2) (=11.2) Math.pow(3,2) (=9)
Math.round() Math.round(5.6) (=6)
Math.frac() Math.frac(5.236) (=0.236)
Math.fabs() Math.fabs(-2.3) (=2.3)
Math.fmod() (floating point mod) Math.fmod(5.3,2) (=1.3)

Comparing Variables

The following table shows different operations for comparing two values or variables.

Operation Example (solution)
> (greater than) 1.7 > 1.7 (false)
< (less than) -1.7 < 1.5 (true)
>= (greater than or equal to) 45 >= 45 (true)
<= (less than or equal to) 45 <= 32 (false)
== (equal to) 45 == 45 (true)
!= (not equal to) 45 != 35 (true)
string comparisons current.name == "Processor5"
pointer comparisons (treenodes, Objects) current == Model.find("Processor5")

Relating Variables

The following table shows different operations for relating several comparisons.

Operation Example
&& (logical AND) x>5 && y<10
|| (logical OR) x==32 || y>45
! (logical NOT) !(x==32 || y>45)
Math.min() Math.min(x, y)
Math.max() Math.max(x, y)

Setting and Changing Variables

The following tables show ways of setting and changing variables.

Operation Example
= x = x + 2;
+= x += 2; (same as x = x + 2)
-= x -= 2; (same as x = x - 2)
*= x *= 2; (same as x = x * 2)
/= x /= 2; (same as x = x / 2)
++ x ++; (same as x = x + 1)
-- x --; (same as x = x - 1)

Executing Commands

Executing a command in FlexSim is made of following parts. First type the command's name, followed by an open parenthesis. Then enter each parameter of the command, separating multiple parameters by commas. Each parameter can be a variable, an expression of variables, or even a command itself. Finish the command with a close parenthesis, and a semi-colon. For detailed information on the commands, their functionality and parameter lists, refer to the "Commands" documentation found through FlexSim's Help menu.

Syntax

commandname(parameter1,parameter2,parameter3...);

Example

getstat(current, "Content", STAT_CURRENT);

Dot Syntax

Classes like the treenode, Object and Variant (to name a few) allow you to call methods, as well as access properties, variables, attributes and labels (if applicable) using dot syntax.

Syntax

object.method(parameter1,parameter2,parameter3...);

Example


		current.setLocation(1, 1, 1);
		treenode lastItem = current.last;
		treenode item3 = current.subnodes[3];
		int quantity = current.quantity; //Accesses label named 'quantity'
		

Flow Constructs

The following are constructs which allow you to modify the flow of your code.

Logical If Statement

The if statement allows you to execute one piece of code if an expression is true, and another piece of code if it is false. The else portion of the construct is optional.

It uses this construct:


		if (test expression)
		{
			code block
		}
		else
		{
			code block
		}
		

For example:


		if (item.subnodes.length == 2)
		{
			item.color = Color.red;
		}
		else
		{
			item.color = Color.black;
		}
		

Logical While Loop

The while loop will continue to loop through its code block until the test expression becomes false.

It uses this construct:


		while (test expression)
		{
			code block
		}
		

For example:


		while (current.subnodes.length > 2)
		{
			current.last.destroy();
		}
		

Logical For Loop

The for loop is like the while loop, except that it is used usually when you know exactly how many times to loop through the code block. The start expression is executed only once, to initialize the loop. The test expression is executed at the beginning of each loop and the loop will stop as soon as this expression is false, just like the while loop. The count expression is executed at the end of each loop, and typically increments some variable, signifying the end of one iteration.

It uses this construct:


		for(start expression; test expression; count expression)
		{
			code block
		}
		

For example:


		for (int index = 1; index <= current.subnodes.length; index++)
		{
			current.subnodes[index].as(Object).color = Color.blue;
		}
		

Logical Switch Statement

The switch statement allows you to choose one piece of code to execute out of several possibilities, depending on a variable to switch on. The switch variable must be an integer type. The example below sets the color of items of type 1 to yellow, type 5 to red, and all other types to green.

It uses this construct:


		switch (switchvariable)
		{
			case casenum:
			{
				code block;
				break;
			}
			default:
			{
				code block;
				break;
			}
		}
		

For example:


		switch (item.type)
		{
			case 1:
			{
				item.color = Color.yellow;
				break;
			}
			case 5:
			{
				item.color = Color.red;
				break;
			}
			default:
			{
				item.color = Color.green;
				break;
			}
		}
		

Redirection

Each of the flow constructs described can be redirected mid-execution with either a continue, break or return statement. The following explains how each of these statements work.

Construct Examples
continue; Only valid in For and While loops. Halts the current iteration of the loop and goes on to the next iteration in the loop. In a For loop the counter is incremented before continuing.
break; Only valid in For, While and Switch statements. Breaks out of the current For, While or Switch block and continues with the line immediately following this block. Nested statements only break out of the current statement and continue on in the containing statement.
return 0; Returns out of the current method entirely and continues with the line following the code that called this method. A value is required after the return statement because all FlexScript commands (picklists and triggers included) return a Variant type. Typing return; is not valid.

Optional Chaining

FlexScript also supports a concept called optional chaining, using the ?. syntax. The need for this arises when there is a possibility of encountering null values in the evaluation of your code. If a given expression results in a null value, and you access a class member of the expression using dot syntax, FlexSim will throw an exception by default.


	treenode nullNode = 0;
	return nullNode.last; // exception
	

Avoiding such exceptions can cause your code to balloon into lots of if statements. Alternately, you can use optional chaining to access class members.


	treenode nullNode = 0;
	return nullNode?.last; // returns null (no exception)
	

If the owning object is null, then the ?.last accessor will simply give back null, instead of throwing an exception. It is called optional chaining because it allows you to chain multiple accessors together very easily without the need for if statement guards. The code will simply bail out and return null when it encounters a null pointer.


	treenode nullNode = 0;
	return nullNode?.first?.first?.first; // returns null (no exception)