TrainzScript Keywords

From TrainzOnline
(Difference between revisions)
Jump to: navigation, search
 
(One intermediate revision by one user not shown)
Line 10: Line 10:
 
*Execution will continue with the first statement after the loop.
 
*Execution will continue with the first statement after the loop.
 
  // This loop will complete when n is greater than 5 or when n == list.size(), whichever occurs first
 
  // This loop will complete when n is greater than 5 or when n == list.size(), whichever occurs first
+
  for (n = 0; n < list.size(); ++n)
  for (n = 0; n < list.size(); n++) {
+
{
   if (n > 5) break;
+
   if (n > 5)
 +
    break;
 
  }
 
  }
 
<br>
 
<br>
Line 22: Line 23:
 
  int i;
 
  int i;
 
  string dayOfWeek;
 
  string dayOfWeek;
  for(i = 0; i < 6; i++) {
+
  for(i = 0; i < 6; ++i)
    switch(i) {
+
{
      case 0 : dayOfWeek = "Sunday";
+
  switch(i)
                break;
+
  {
      case 1 : dayOfWeek = "Monday";
+
    case 0:
                break;
+
      dayOfWeek = "Sunday";
      case 2 : dayOfWeek = "Tuesday";
+
      break;
                break;
+
    case 1:
      case 3 : dayOfWeek = "Wednesday";
+
      dayOfWeek = "Monday";
                break;
+
      break;
      case 4 : dayOfWeek = "Thursday";
+
    case 2:
                break;
+
      dayOfWeek = "Tuesday";
      case 5 : dayOfWeek = "Friday";
+
      break;
                break;
+
    case 3:
      case 6 : dayOfWeek = "Saturday";
+
      dayOfWeek = "Wednesday";
                break;
+
      break;
      default : dayOfWeek = "ERROR";
+
    case 4:
    }
+
      dayOfWeek = "Thursday";
    Interface.Print(dayOfWeek);
+
      break;
 +
    case 5:
 +
      dayOfWeek = "Friday";
 +
      break;
 +
    case 6:
 +
      dayOfWeek = "Saturday";
 +
      break;
 +
    default:
 +
      dayOfWeek = "ERROR";
 +
      break;
 +
  }
 +
 
 +
  Interface.Print(dayOfWeek);
 
  }
 
  }
*''[[#Switch|switch]]'' transfers execution to the statement immedaitely following the appropriate ''case'' label.
+
*''[[#Switch|switch]]'' transfers execution to the statement immediately following the appropriate ''case'' label.
 
*If there is no match execution continues after the ''[[#default|default]]'' label.
 
*If there is no match execution continues after the ''[[#default|default]]'' label.
 
*Note that the list of statements following the ''case'' selector should normally terminate with ''[[#break|break]];'' (which exits from the ''[[#switch|switch]]'' statement) or ''[[#return|return]]'' (which exits from the entire method) to prevent the code from running on into the next section.
 
*Note that the list of statements following the ''case'' selector should normally terminate with ''[[#break|break]];'' (which exits from the ''[[#switch|switch]]'' statement) or ''[[#return|return]]'' (which exits from the entire method) to prevent the code from running on into the next section.
Line 49: Line 62:
 
{{MethodHeader|<h4>class</h4>}}
 
{{MethodHeader|<h4>class</h4>}}
 
*Class defines a new class declaration and the identity of the immediate parent:
 
*Class defines a new class declaration and the identity of the immediate parent:
  class ChildClass isclass ParentClass {
+
  class ChildClass isclass ParentClass
 +
{
 
   
 
   
 
   class members...
 
   class members...
Line 61: Line 75:
 
*Jumps to the next iteration of a ''[[#for|for]], [[#while|while]]'' or ''[[#wait|wait]]'' loop For example:
 
*Jumps to the next iteration of a ''[[#for|for]], [[#while|while]]'' or ''[[#wait|wait]]'' loop For example:
 
  int i;
 
  int i;
  for(i = 0; i < 10; ++i) {
+
  for(i = 0; i < 10; ++i)
    if(i == 5)  
+
{
    continue;
+
  if (i == 5)  
    Interface.Print(i);
+
    continue;
 +
  Interface.Print(i);
 
  }
 
  }
 
*The above code will print 0 to 4, skip 5 and then print 6 to 9.
 
*The above code will print 0 to 4, skip 5 and then print 6 to 9.
Line 91: Line 106:
 
{{MethodHeader|<h4>final</h4>}}
 
{{MethodHeader|<h4>final</h4>}}
 
*A class or method specifier that prevents users from overriding the declaration
 
*A class or method specifier that prevents users from overriding the declaration
  final class Info {
+
  final class Info
 +
{
 
   string name;
 
   string name;
 
   string address;
 
   string address;
 
  }
 
  }
 
*Given the above the declaration the following declaration would not be possible
 
*Given the above the declaration the following declaration would not be possible
  class DetailedInfo isclass Info {
+
  class DetailedInfo isclass Info
 +
{
 
   string telephone;
 
   string telephone;
 
  }
 
  }
Line 108: Line 125:
 
**C is the loop expression, and will be executed at the end of every loop
 
**C is the loop expression, and will be executed at the end of every loop
 
**D is the code body statement, usually a compound statement, and is executed on every loop.
 
**D is the code body statement, usually a compound statement, and is executed on every loop.
 +
Junction[] junctions = GetJunctionList();
 
  int i;
 
  int i;
Junction[] junctions = World.GetJunctionList();
+
  for (i = 0; i < junctions.size(); ++i)
  for (i = 0; i < junctions.size(); i++) {
+
{
    string name = junctions[i].GetName();
+
  string name = junctions[i].GetLocalisedName();
    Interface.Print("Junction " + i + " is called " + name);
+
  Interface.Print("Junction " + i + " is named: " + name);
 
  }
 
  }
 
*Depending on the values of Parts A and B the loop may not execute at all.
 
*Depending on the values of Parts A and B the loop may not execute at all.
Line 123: Line 141:
 
{{MethodHeader|<h4>goto</h4>}}
 
{{MethodHeader|<h4>goto</h4>}}
 
*The ''goto'' statement will branch to a label statement. For example:
 
*The ''goto'' statement will branch to a label statement. For example:
  int i = 5
+
  int i = 5;
 
   
 
   
  A: // label statement
+
  label_A:
 
  Interface.Print("hello");
 
  Interface.Print("hello");
  if(i--) goto A;
+
  if (i--)
 +
  goto label_A;
  
 
*The above code will print hello 5 times. (zero evaluates as boolean false)
 
*The above code will print hello 5 times. (zero evaluates as boolean false)
Line 139: Line 158:
 
  int i = Math.Rand(0, 3);
 
  int i = Math.Rand(0, 3);
 
   
 
   
  if (i == 0) {
+
  if (i == 0)
    Interface.Print("i is 0");
+
{
 +
  Interface.Print("i is 0");
 
  }
 
  }
  else if (i == 1) {
+
  else if (i == 1)
    Interface.Print("i is 1");
+
{
 +
  Interface.Print("i is 1");
 
  }
 
  }
  else {
+
  else
    Interface.Print("i is 2");
+
{
 +
  Interface.Print("i is 2");
 
  }
 
  }
 
<br>
 
<br>
Line 192: Line 214:
  
 
{{MethodHeader|<h4>obsolete</h4>}}
 
{{MethodHeader|<h4>obsolete</h4>}}
*Indicates that the function is obsolete and should not be used.
+
*Indicates that the function is obsolete and should not be used, except to support/load legacy saved data.
*Obsolete functions may not operate and/or generate errors in certain [[Compatibility_mode|Compatibility mode settings]].
+
*Obsolete functions may not operate and/or may generate errors in certain [[Compatibility_mode|Compatibility mode settings]].
 
*Some functions are marked obsolete because their features are not supported, but many will have modern replacements.
 
*Some functions are marked obsolete because their features are not supported, but many will have modern replacements.
 
*See also: [[#legacy_compatibility|legacy_compatibility]]
 
*See also: [[#legacy_compatibility|legacy_compatibility]]
Line 220: Line 242:
 
     public string forename;              // Public member variable
 
     public string forename;              // Public member variable
 
     public string surname;              // Public member variable
 
     public string surname;              // Public member variable
 
+
   
 
     // Public function
 
     // Public function
 
     public string GetName(void)
 
     public string GetName(void)
Line 254: Line 276:
 
*Threaded methods may only be declared in classes extending the GameObject class or its children.
 
*Threaded methods may only be declared in classes extending the GameObject class or its children.
 
*Many threads (up to 64) may be running on the same game object instance at a time.
 
*Many threads (up to 64) may be running on the same game object instance at a time.
  class Tutorial isclass Buildable {
+
  class Tutorial isclass Buildable
   
+
  {
 +
  bool bThreadRunning = false;
 
   bool doorsOpen = false;
 
   bool doorsOpen = false;
 
   
 
   
   public void Init(void) {
+
   public void Init(void)
      inherited();
+
  {
      AddHandler(me,"Object","","ObjectHandler");
+
    inherited();
 +
    AddHandler(me, "Object", "", "ObjectHandler");
 
   }
 
   }
 
   
 
   
   thread void RingTheBell(void) {
+
   thread void RingTheBell(void)
       while (doorsOpen) {
+
  {
        Sleep(0.35 + World.Play2DSound(GetAsset(),"bell.wav"));
+
      // Make sure we don't run multiple 'RingTheBell' threads at once.
 +
      if (bThreadRunning)
 +
        return;
 +
      bThreadRunning = true;
 +
     
 +
       while (doorsOpen)
 +
      {
 +
        // Play sound file
 +
        World.Play2DSound(GetAsset(),"bell.wav");
 +
       
 +
        // Wait for sound file to finish
 +
        Sleep(0.35);
 
       }
 
       }
 +
     
 +
      bThreadRunning = true;
 
   }
 
   }
+
 
   void ObjectHandler(Message msg) {
+
   void ObjectHandler(Message msg)
       if (msg.minor == "Enter") {
+
  {
 +
       if (msg.minor == "Enter")
 +
      {
 
         doorsOpen = true;
 
         doorsOpen = true;
 
         RingTheBell();
 
         RingTheBell();
 
       }
 
       }
       else doorsOpen = false;
+
       else
 +
      {
 +
        doorsOpen = false;
 +
      }
 
   }
 
   }
 
   
 
   
 
  };
 
  };
*In the above the ''thread RingTheBell'' is started on an ''Object,Enter'' message and will terminate on any other ''Object'' message, irrespective of other code within the class.
+
*In the above the ''thread RingTheBell'' is started on an ''Object,Enter'' message and will terminate on any other ''Object'' message.
 
<br>
 
<br>
  
Line 290: Line 332:
 
*to indicate that a method requires no parameters
 
*to indicate that a method requires no parameters
 
*to indicate that a method does not return a value
 
*to indicate that a method does not return a value
  public void DoTheDo(void);
+
  public void DoTheDo(void) { }
 
<br>
 
<br>
  
Line 297: Line 339:
 
*It can listen for multiple message types using the on statement.
 
*It can listen for multiple message types using the on statement.
 
*When a wait statement is executed, execution stops on the thread until one of the on conditions is met.
 
*When a wait statement is executed, execution stops on the thread until one of the on conditions is met.
  wait() {
+
  wait()
     on "hello", "world" : {
+
{
 +
     on "hello", "world" :
 +
    {
 
       // code here will execute for any ''hello,world'' message and then continue to wait for other messages.
 
       // code here will execute for any ''hello,world'' message and then continue to wait for other messages.
 
       continue;
 
       continue;
 
     }
 
     }
     on "hi", "there" : {
+
     on "hi", "there" :
 +
    {
 
       // code here will execute for any ''hi,there'' message and then exit the loop.
 
       // code here will execute for any ''hi,there'' message and then exit the loop.
 
       break;
 
       break;
Line 318: Line 363:
 
*Note that if the condition is initially false the loop will not run at all
 
*Note that if the condition is initially false the loop will not run at all
 
  int i = 5;
 
  int i = 5;
  while (i > 0) {
+
  while (i > 0)
   Interface.Print("i is greater than zero");
+
{
 +
   Interface.Print("i is greater than zero (" + i + ")");
 +
  --i;
 
  }
 
  }
 
<br>
 
<br>

Latest revision as of 11:11, 3 March 2022


Contents

[edit] Keywords

break

  • Exits from current code block (for, wait, switch, while)
  • Execution will continue with the first statement after the loop.
// This loop will complete when n is greater than 5 or when n == list.size(), whichever occurs first
for (n = 0; n < list.size(); ++n)
{
  if (n > 5)
    break;
}


case

  • Individual case statements are labels that the code will jump to dependent on the value of the integer expression following the keyword.
  • The case statement is used in the switch control flow statement to declare an integer option and the action to be taken when execution is transferred to this label.
  • This code will print the days of the week from Sunday to Saturday:
int i;
string dayOfWeek;
for(i = 0; i < 6; ++i)
{
  switch(i)
  {
    case 0:
      dayOfWeek = "Sunday";
      break;
    case 1:
      dayOfWeek = "Monday";
      break;
    case 2:
      dayOfWeek = "Tuesday";
      break;
    case 3:
      dayOfWeek = "Wednesday";
      break;
    case 4:
      dayOfWeek = "Thursday";
      break;
    case 5:
      dayOfWeek = "Friday";
      break;
    case 6:
      dayOfWeek = "Saturday";
      break;
    default:
      dayOfWeek = "ERROR";
      break;
  }
  Interface.Print(dayOfWeek);
}
  • switch transfers execution to the statement immediately following the appropriate case label.
  • If there is no match execution continues after the default label.
  • Note that the list of statements following the case selector should normally terminate with break; (which exits from the switch statement) or return (which exits from the entire method) to prevent the code from running on into the next section.


class

  • Class defines a new class declaration and the identity of the immediate parent:
class ChildClass isclass ParentClass
{

 class members...
 class methods...

};
  • More than one class declaration may be included in the same file.


continue

  • Jumps to the next iteration of a for, while or wait loop For example:
int i;
for(i = 0; i < 10; ++i)
{
  if (i == 5) 
    continue;
  Interface.Print(i);
}
  • The above code will print 0 to 4, skip 5 and then print 6 to 9.


default


define

  • define is used to declare a constant
  • Constants must be initialised on declaration and cannot be changed in code.
define string firstDay = "Monday";  // declares a string variable available anywhere within the containing class
define public int daysInWeek = 7;   // declares an integer variable which will also be available from outside the class.


else


false

  • Boolean constant
!true = false


final

  • A class or method specifier that prevents users from overriding the declaration
final class Info
{
  string name;
  string address;
}
  • Given the above the declaration the following declaration would not be possible
class DetailedInfo isclass Info
{
  string telephone;
}


for

  • for is a control flow loop statement.
  • A for loop has four parts and takes the form: for(A; B; C) D where:
    • A initialises a counter variable, and is executed before the looping begins
    • B is the test condition, looping will continue while B is true
    • C is the loop expression, and will be executed at the end of every loop
    • D is the code body statement, usually a compound statement, and is executed on every loop.
Junction[] junctions = GetJunctionList();
int i;
for (i = 0; i < junctions.size(); ++i)
{
  string name = junctions[i].GetLocalisedName();
  Interface.Print("Junction " + i + " is named: " + name);
}
  • Depending on the values of Parts A and B the loop may not execute at all.


game

  • Class specifier reserved for built-in predefined classes.


goto

  • The goto statement will branch to a label statement. For example:
int i = 5;

label_A:
Interface.Print("hello");
if (i--)
 goto label_A;
  • The above code will print hello 5 times. (zero evaluates as boolean false)


if

  • if and else are keywords for the construction of if / then / else constructs used to control program flow
  • Code following an if(condition) statement is executed only when the condition evaluates to true.
  • In any other case execution branches to any immediately following else statement.
  • else and else if clauses are optional.
int i = Math.Rand(0, 3);

if (i == 0)
{
  Interface.Print("i is 0");
}
else if (i == 1)
{
  Interface.Print("i is 1");
}
else
{
  Interface.Print("i is 2");
}


include

  • Syntax: include "filename.gs"
  • This statement must appear before any class declarations and will include the contents of the specified script file.
  • It is generally sufficient to include the *.gs filename related to the immediate parent of your script.


inherited

  • an inherited() statement is made within a method definition to call the corresponding method in the immediate parent of the class.
  • inherited() returns the same type, and takes the same parameters as the parent method.
  • Inheritance is central to Object Oriented Programming, you should not omit these calls.


legacy_compatibility

  • The legacy_compatibility keyword indicates that a specific function exists in order to support legacy usage only.
  • A function with the legacy_compatibility keyword will not generate compiler warnings about obsolete function usages.
  • legacy_compatibility functions are most commonly used to load and upgrade legacy data formats.
  • See also: obsolete


mandatory

  • mandatory is a method specifier which indicates that, if the method is over-ridden the over-ridden method must call inherited.


me

  • me refers to the current object, similar to self or this keywords in other languages.
  • me is used to overcome ambiguity of variable scope, or use the current object as a function parameter.
  • me is often understood if not stated, these statements would have the same effect:
me.SetMeshAnimationState();
SetMeshAnimationState()


native

  • A method specifier which indicates that the method is implemented by the games "native code" rather than in script code.


null

  • null is an uninitialised expression.
  • Every reference that is not assigned to an object has the value null.
  • Assigning null to an existing object will remove that reference to that object. When no references remain, the object will be deleted.


obsolete

  • Indicates that the function is obsolete and should not be used, except to support/load legacy saved data.
  • Obsolete functions may not operate and/or may generate errors in certain Compatibility mode settings.
  • Some functions are marked obsolete because their features are not supported, but many will have modern replacements.
  • See also: legacy_compatibility


on


public

  • A specifier indicating that the member or method is accessible by other classes.


return

  • Exits immediately from the current method, used when the method return type is void.
  • or exit from the current method returning value to the calling routine.
  • Value must match the method return type.


static

  • static is a class specifier denoting that only one instance of the class may exist.
  • Static classes cannot be created using the new operator.
  • To access a static class refer to its members or methods using the class name as follows:
static class Owner
{
   public string forename;              // Public member variable
   public string surname;               // Public member variable
   
   // Public function
   public string GetName(void)
   {
     return forename + " " + surname;
   }

};

class Postbox isclass MapObject
{
   public void Init(void)
   {
      if (!Owner.forename)
        Owner.forename = "Fred";
      if (!Owner.surname)
        Owner.surname = "Bloggs";
      Interface.Print(Owner.GetName());
   }
}
  • Since only one instance of owner may exist it will be created along with the first instance of the postbox obect
  • Any future postboxes will find the members of the owner class already initialised and ready for use.


switch


thread

  • A thread is a method which runs independently of the main script code.
  • threads can be started and synchronised by standard methods or other threads but are allowed to wait for events or to carry out tasks requiring periods of inactivity without interrupting the main program flow.
  • Threaded methods may only be declared in classes extending the GameObject class or its children.
  • Many threads (up to 64) may be running on the same game object instance at a time.
class Tutorial isclass Buildable
{
  bool bThreadRunning = false;
  bool doorsOpen = false;

  public void Init(void)
  {
    inherited();
    AddHandler(me, "Object", "", "ObjectHandler");
  }

  thread void RingTheBell(void)
  {
     // Make sure we don't run multiple 'RingTheBell' threads at once.
     if (bThreadRunning)
       return;
     bThreadRunning = true;
     
     while (doorsOpen)
     {
       // Play sound file
       World.Play2DSound(GetAsset(),"bell.wav");
       
       // Wait for sound file to finish
       Sleep(0.35);
     }
     
     bThreadRunning = true;
  }
  
  void ObjectHandler(Message msg)
  {
     if (msg.minor == "Enter")
     {
        doorsOpen = true;
        RingTheBell();
     }
     else
     {
       doorsOpen = false;
     }
  }

};
  • In the above the thread RingTheBell is started on an Object,Enter message and will terminate on any other Object message.


true

  • Boolean constant
!false = true


void

  • void is a null type used in two situations:
  • to indicate that a method requires no parameters
  • to indicate that a method does not return a value
public void DoTheDo(void) { }


wait

  • wait is a control flow statement that suspends execution of a thread pending receipt of a message of a given type.
  • It can listen for multiple message types using the on statement.
  • When a wait statement is executed, execution stops on the thread until one of the on conditions is met.
wait()
{
   on "hello", "world" :
   {
      // code here will execute for any hello,world message and then continue to wait for other messages.
      continue;
   }
   on "hi", "there" :
   {
      // code here will execute for any hi,there message and then exit the loop.
      break;
   }
   on "hey", "" :
   {
      // code here will execute for any message with a major type of
      // "hey" this will break by default, terminating the wait() loop.
   }
 }


while

  • A while(condition) is a loop control method that will continue as long as its condition evaluates to true.
  • Note that if the condition is initially false the loop will not run at all
int i = 5;
while (i > 0)
{
  Interface.Print("i is greater than zero (" + i + ")");
  --i;
}



[edit] Categories

Personal tools