TrainzScript Keywords
From TrainzOnline
(Difference between revisions)
(7 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
+ | * [[TrainzScript Language Reference]] | ||
+ | ** [[Comments & Delineation]] | ||
+ | ** [[TrainzScript Keywords]] | ||
+ | ** [[Operators]] | ||
+ | ** [[Types]] | ||
+ | <br /> | ||
==Keywords== | ==Keywords== | ||
− | |||
{{MethodHeader|<h4>break</h4>}} | {{MethodHeader|<h4>break</h4>}} | ||
*Exits from current code block (''[[#for|for]], [[#wait|wait]], [[#switch|switch]], [[#while|while]]'') | *Exits from current code block (''[[#for|for]], [[#wait|wait]], [[#switch|switch]], [[#while|while]]'') | ||
*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(); | + | { |
− | if (n > 5) break; | + | if (n > 5) |
+ | break; | ||
} | } | ||
<br> | <br> | ||
Line 17: | Line 23: | ||
int i; | int i; | ||
string dayOfWeek; | string dayOfWeek; | ||
− | for(i = 0; i < 6; | + | 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|switch]]'' transfers execution to the statement | + | *''[[#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 44: | 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 56: | 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; | |
+ | 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 86: | 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 103: | 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; | ||
− | + | for (i = 0; i < junctions.size(); ++i) | |
− | for (i = 0; i < junctions.size(); | + | { |
− | + | 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. | *Depending on the values of Parts A and B the loop may not execute at all. | ||
Line 118: | 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; |
− | + | label_A: | |
Interface.Print("hello"); | Interface.Print("hello"); | ||
− | if(i--) goto | + | 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 134: | 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"); | ||
} | } | ||
− | else if (i == 1) { | + | else if (i == 1) |
− | + | { | |
+ | Interface.Print("i is 1"); | ||
} | } | ||
− | else { | + | else |
− | + | { | |
+ | Interface.Print("i is 2"); | ||
} | } | ||
<br> | <br> | ||
Line 155: | Line 182: | ||
*inherited() returns the same type, and takes the same parameters as the parent method. | *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. | *Inheritance is central to Object Oriented Programming, you should not omit these calls. | ||
+ | <br> | ||
+ | |||
+ | {{MethodHeader|<h4>legacy_compatibility</h4>}} | ||
+ | *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|obsolete]] | ||
+ | <br> | ||
+ | |||
+ | {{MethodHeader|<h4>mandatory</h4>}} | ||
+ | *mandatory is a method specifier which indicates that, if the method is over-ridden the over-ridden method '''must''' call ''inherited''. | ||
<br> | <br> | ||
{{MethodHeader|<h4>me</h4>}} | {{MethodHeader|<h4>me</h4>}} | ||
*me refers to the current object, similar to ''self'' or ''this'' keywords in other languages. | *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 is often understood if not stated, these statements would have the same effect: | ||
me.SetMeshAnimationState(); | me.SetMeshAnimationState(); | ||
Line 165: | Line 204: | ||
{{MethodHeader|<h4>native</h4>}} | {{MethodHeader|<h4>native</h4>}} | ||
− | *A method specifier which indicates that the method is implemented by the | + | *A method specifier which indicates that the method is implemented by the games "native code" rather than in script code. |
<br> | <br> | ||
Line 171: | Line 210: | ||
*null is an uninitialised expression. | *null is an uninitialised expression. | ||
*Every reference that is not assigned to an object has the value null. | *Every reference that is not assigned to an object has the value null. | ||
− | *Assigning null to an existing object will | + | *Assigning null to an existing object will remove that reference to that object. When no references remain, the object will be deleted. |
+ | <br> | ||
+ | |||
+ | {{MethodHeader|<h4>obsolete</h4>}} | ||
+ | *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|Compatibility mode settings]]. | ||
+ | *Some functions are marked obsolete because their features are not supported, but many will have modern replacements. | ||
+ | *See also: [[#legacy_compatibility|legacy_compatibility]] | ||
<br> | <br> | ||
Line 179: | Line 225: | ||
{{MethodHeader|<h4>public</h4>}} | {{MethodHeader|<h4>public</h4>}} | ||
− | *A specifier indicating that the member or method is accessible | + | *A specifier indicating that the member or method is accessible by other classes. |
<br> | <br> | ||
Line 192: | Line 238: | ||
*Static classes cannot be created using the new operator. | *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: | *To access a static class refer to its members or methods using the class name as follows: | ||
− | static class | + | static class Owner |
− | + | { | |
− | public string forename; // | + | public string forename; // Public member variable |
− | public string surname; // | + | public string surname; // Public member variable |
− | public string GetName(void) { | + | |
− | + | // Public function | |
+ | public string GetName(void) | ||
+ | { | ||
+ | return forename + " " + surname; | ||
} | } | ||
}; | }; | ||
− | class | + | class Postbox isclass MapObject |
− | + | { | |
− | public void Init(void) { | + | public void Init(void) |
− | if (! | + | { |
− | if (! | + | if (!Owner.forename) |
− | Interface.Print( | + | 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 | *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. | *Any future postboxes will find the members of the owner class already initialised and ready for use. | ||
Line 224: | 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"); | ||
} | } | ||
− | thread void RingTheBell(void) { | + | thread void RingTheBell(void) |
− | while (doorsOpen) { | + | { |
− | + | // 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 | + | *In the above the ''thread RingTheBell'' is started on an ''Object,Enter'' message and will terminate on any other ''Object'' message. |
<br> | <br> | ||
Line 260: | 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 267: | 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 288: | 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> | ||
+ | |||
+ | |||
+ | =Categories= | ||
+ | [[Category:TrainzScript]] |
Latest revision as of 11:11, 3 March 2022
- TrainzScript Language Reference
- Comments & Delineation
- TrainzScript Keywords
- Operators
- Types
[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
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
- See case.
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
- see if
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
- see wait()
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
- See case.
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; }