Scripting: Keywords – Arma Reforger
Jump to navigation
Jump to search
biki>Lou Montana m (Some wiki formatting) |
Lou Montana (talk | contribs) m (Fix vanilla description) |
||
(22 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{TOC|side}} | {{TOC|side}} | ||
{{TOC|subTOC|content= | |||
* 1 {{Link|#Class Keywords}} | |||
* 2 {{Link|#Method Keywords}} | |||
* 3 {{Link|#Values Keywords}} | |||
* 4 {{Link|#Code Keywords}} | |||
* 5 {{Link|#Code Flow Keywords}} | |||
}} | |||
== Class Keywords == | == Class Keywords == | ||
{| class="wikitable" | {| class="wikitable valign-top" | ||
|- | ! Keyword | ||
! Description | |||
|- | |||
! | ! | ||
=== class === | === class === | ||
| Declares a class | | Declares a class | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== modded === | === modded === | ||
| See | | See {{Link|Arma Reforger:Object Oriented Programming Advanced Usage#Modding}}. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
} | } | ||
modded class ExampleClass // inherits and "takes the place" of the original ExampleClass | modded class ExampleClass // inherits and "takes the place" of the original ExampleClass | ||
{ | { | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== sealed === | === sealed === | ||
| A class marked with the '''sealed''' keyword cannot be inherited from | | A class marked with the '''sealed''' keyword cannot be inherited from | ||
< | <enforce> | ||
sealed class Infertile | sealed class Infertile | ||
{ | { | ||
} | } | ||
class Child : Infertile // compilation error - a class cannot inherit from a sealed class | class Child : Infertile // compilation error - a class cannot inherit from a sealed class | ||
{ | { | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== extends === | === extends === | ||
| states that the declared class inherits from another | | states that the declared class inherits from another | ||
< | <enforce> | ||
class ChildClass extends ParentClass | class ChildClass extends ParentClass | ||
{ | { | ||
} | } | ||
// alias | // alias | ||
class ChildClass : ParentClass | class ChildClass : ParentClass | ||
{ | { | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== typedef === | === typedef === | ||
| Declares an alias for a type | | Declares an alias for a type | ||
< | <enforce> | ||
typedef string Text; | typedef string Text; | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Text m_sMyText = "This is my text, that is a string"; | Text m_sMyText = "This is my text, that is a string"; | ||
} | } | ||
</ | </enforce> | ||
|} | |} | ||
Line 69: | Line 78: | ||
== Method Keywords == | == Method Keywords == | ||
{| class="wikitable" | {| class="wikitable valign-top" | ||
|- | ! Keyword | ||
! Description | |||
|- | |||
! | ! | ||
=== proto === | === proto === | ||
| | | Disclose an engine-side method to script (Engine side). | ||
|- | |- | ||
! | |||
=== external === | |||
| Compiler hint to link API methods - only applies to {{hl|proto}} methods (Engine side). | |||
|- | |||
! | ! | ||
=== native === | === native === | ||
| Native call convention of internal | | Native call convention of internal method (Engine side). | ||
|- | |- | ||
! | ! | ||
=== volatile === | === volatile === | ||
| Internal | | Internal method that may call back to script (hint for compiler that context need to be saved on stack). | ||
|- | |- | ||
! | ! | ||
=== private === | === private === | ||
| Modifier for class method. The method can be called only from inside of the same class' methods. A modded class will '''not''' be able to use it either. | | Modifier for class method. The method can be called only from inside of the same class' methods. A modded class will '''not''' be able to use it either. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 99: | Line 114: | ||
} | } | ||
} | } | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld() | classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld() | ||
classInstance.HelloWorld(); // compilation error - HelloWorld() is private and cannot be accessed | classInstance.HelloWorld(); // compilation error - HelloWorld() is private and cannot be accessed | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== protected === | === protected === | ||
| Modifier for class method. The method can be called only from inside of class' methods or methods of its extended (children) classes, or a modded class. | | Modifier for class method. The method can be called only from inside of class' methods or methods of its extended (children) classes, or a modded class. | ||
< | <enforce> | ||
class ParentClass | class ParentClass | ||
{ | { | ||
Line 124: | Line 139: | ||
} | } | ||
} | } | ||
ChildClass classInstance = new ChildClass(); | ChildClass classInstance = new ChildClass(); | ||
classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld() | classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld() | ||
classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed | classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed | ||
ParentClass classInstance = new ParentClass(); | ParentClass classInstance = new ParentClass(); | ||
classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed | classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== static === | === static === | ||
| Modifier for class method. The method can be called without object pointer, just by ClassName.methodName(). Only static values/methods can be accessed from a static method. | | Modifier for class method. The method can be called without object pointer, just by ClassName.methodName(). Only static values/methods can be accessed from a static method. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 144: | Line 159: | ||
} | } | ||
} | } | ||
ExampleClass.HelloWorld(); // works | ExampleClass.HelloWorld(); // works | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
classInstance.HelloWorld(); // works | classInstance.HelloWorld(); // works | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== event === | === event === | ||
| Hint for tools that the | | Hint for tools that the method should be exposed as Entity script event. | ||
|- | |- | ||
! | ! | ||
=== override === | === override === | ||
| Modifier for class method indicating overriding of base class method. Compiler checks if is method present in base class and if method signature matches. | | Modifier for class method indicating overriding of base class method. Compiler checks if is method present in base class and if method signature matches. | ||
< | <enforce> | ||
class ParentClass | class ParentClass | ||
{ | { | ||
Line 174: | Line 189: | ||
} | } | ||
} | } | ||
ParentClass parentClassInstance = new ParentClass(); | ParentClass parentClassInstance = new ParentClass(); | ||
parentClassInstance.HelloWorld(); // prints "Hello world" | parentClassInstance.HelloWorld(); // prints "Hello world" | ||
ChildClass childClassInstance = new ChildClass(); | ChildClass childClassInstance = new ChildClass(); | ||
childClassInstance.HelloWorld(); // prints "Hello there" | childClassInstance.HelloWorld(); // prints "Hello there" | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== sealed === | === sealed === | ||
| Modifier for class method. The method cannot be overridden in derived classes. | | Modifier for class method. The method cannot be overridden in derived classes. | ||
< | <enforce> | ||
class ParentClass | class ParentClass | ||
{ | { | ||
Line 193: | Line 208: | ||
} | } | ||
} | } | ||
class ChildClass : ParentClass | class ChildClass : ParentClass | ||
{ | { | ||
Line 201: | Line 216: | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|} | |} | ||
Line 207: | Line 222: | ||
== Value Keywords == | == Value Keywords == | ||
{| class="wikitable" | {| class="wikitable valign-top" | ||
|- | ! Keyword | ||
! Description | |||
|- | |||
! | ! | ||
=== owned === | === owned === | ||
| Modifier for returning internal | | Modifier for returning internal methods. Tells the script VM that the returning variable (string or array) must not be released. | ||
|- | |- | ||
! | ! | ||
=== out === | === out === | ||
| Modifier for | | Modifier for method parameters. It means that the argument may be changed by the method call. | ||
< | <enforce> | ||
void Method(out array<string> parameter) | void Method(out array<string> parameter) | ||
{ | { | ||
parameter = | parameter = {}; | ||
parameter.Insert("Hello"); | parameter.Insert("Hello"); | ||
parameter.Insert("there"); | parameter.Insert("there"); | ||
} | } | ||
// ... | // ... | ||
array<string> myArray = null; | array<string> myArray = null; | ||
Method( | Method(myArray); // myArray is now { "Hello", "there" } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== inout === | === inout === | ||
| Modifier for | | Modifier for method parameters. It means that the argument will be used and may be changed by the method call. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
private ref array<string> | private ref array<string> m_aOldParameter; | ||
void Method(inout array<string> parameter) | void Method(inout array<string> parameter) | ||
{ | { | ||
parameter = | m_aOldParameter = parameter; | ||
parameter = {}; | |||
parameter.Insert("Hello"); | parameter.Insert("Hello"); | ||
parameter.Insert("there"); | parameter.Insert("there"); | ||
} | } | ||
} | } | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
array<string> myArray = null; | array<string> myArray = null; | ||
classInstance.Method( | classInstance.Method(myArray); // myArray is now { "Hello", "there" } and classInstance.m_aList is referencing myArray's old value | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== const === | === const === | ||
| Declares a constant, that is a value that cannot be modified later. | | Declares a constant, that is a value that cannot be modified later. | ||
< | <enforce> | ||
const string MY_TEXT = "Hello there"; | const string MY_TEXT = "Hello there"; | ||
void | void Method1() | ||
{ | { | ||
Print(MY_TEXT); // will print "Hello there" | Print(MY_TEXT); // will print "Hello there" | ||
MY_TEXT = "General Kenobi"; // compilation error - a constant is set in stone and cannot be modified | MY_TEXT = "General Kenobi"; // compilation error - a constant is set in stone and cannot be modified | ||
} | } | ||
</ | |||
|- | void Method2() | ||
{ | |||
const string myUnmodifiableString = "Hello there"; // constant valid for method's scope | |||
Print(myUnmodifiableString); | |||
myUnmodifiableString = "General Kenobi"; // compilation error | |||
} | |||
</enforce> | |||
|- | |||
! | ! | ||
=== reference === | === reference === | ||
| Hint for tools (Material editor) that the value may be used as parameter in material. | | Hint for tools (Material editor) that the value may be used as parameter in material. | ||
|- | |- | ||
! | ! | ||
=== notnull === | === notnull === | ||
| Modifier for | | Modifier for method parameter of class pointer type. It means that the method expect the parameter to never be '''null'''; if a null value is provided, a VM Exception is raised and the method is not called. | ||
< | <enforce> | ||
void Method(notnull IEntity entity) // no need to check for "if (!entity)" inside the method | void Method(notnull IEntity entity) // no need to check for "if (!entity)" inside the method | ||
{ | { | ||
entity.DoSomething(); // the argument can be accessed safely | entity.DoSomething(); // the argument can be accessed safely | ||
} | } | ||
if (myEntity) // it is still needed to check for null before calling the method | if (myEntity) // it is still needed to check for null before calling the method | ||
{ | { | ||
Method(myEntity); | Method(myEntity); | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== private === | === private === | ||
| Value can only be accessed from the class/instance methods. Mutually exclusive with "protected". | | Value can only be accessed from the class/instance methods. Mutually exclusive with "protected". | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 299: | Line 323: | ||
} | } | ||
} | } | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
Print(classInstance.m_bIsActive); // compilation error - m_bIsActive is private and cannot be accessed | Print(classInstance.m_bIsActive); // compilation error - m_bIsActive is private and cannot be accessed | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== protected === | === protected === | ||
| Value can only be accessed from the class/instance methods or its children. Mutually exclusive with "private". | | Value can only be accessed from the class/instance methods or its children. Mutually exclusive with "private". | ||
< | <enforce> | ||
class ParentClass | class ParentClass | ||
{ | { | ||
Line 318: | Line 342: | ||
} | } | ||
} | } | ||
class ChildClass : ParentClass | class ChildClass : ParentClass | ||
{ | { | ||
Line 326: | Line 350: | ||
} | } | ||
} | } | ||
ChildClass childClassInstance = new ChildClass(); | ChildClass childClassInstance = new ChildClass(); | ||
Print(childClassInstance.m_bProtected); // compilation error - m_bProtected is protected and cannot be accessed | Print(childClassInstance.m_bProtected); // compilation error - m_bProtected is protected and cannot be accessed | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== static === | === static === | ||
| Value belongs to the class and not an instance of it. If public, it can be accessed without object pointer, just by < | | Value belongs to the class and not an instance of it. If public, it can be accessed without object pointer, just by <enforce>ClassName.variable</enforce> | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 340: | Line 364: | ||
private static bool m_bPrivate; // it is good practice to make it protected/private and have getters/setters instead | private static bool m_bPrivate; // it is good practice to make it protected/private and have getters/setters instead | ||
} | } | ||
Print(ExampleClass.bStaticValue); // works | Print(ExampleClass.bStaticValue); // works | ||
ExampleClass.bStaticValue = true; // works | ExampleClass.bStaticValue = true; // works | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
Print(classInstance.bStaticValue); // works | Print(classInstance.bStaticValue); // works | ||
classInstance.bStaticValue = true; // works | classInstance.bStaticValue = true; // works | ||
</ | </enforce> | ||
|- | {{Feature|warning|Due to the nature of per-scenario mod loading/unloading, {{hl|static}} properties '''are reset game-wide''' on modded scenario start/leave due to game and scripts' entire reload.}} | ||
|- | |||
! | ! | ||
=== autoptr === | === autoptr === | ||
| Modifier for class/pointer values. Pointed object will be automatically destroyed upon end of variable lifetime (end of scope, or deletion of class, that contain it). | | Modifier for class/pointer values. Pointed object will be automatically destroyed upon end of variable lifetime (end of scope, or deletion of class, that contain it). | ||
|- | {{Feature|informative|This keyword is useless in scripting as all classes inherit {{hl|Managed}}, therefore are managed by [[Arma Reforger:Scripting: Automatic Reference Counting|ARC]].}} | ||
|- | |||
! | ! | ||
=== ref === | === ref === | ||
| Strong reference. | | Strong reference. See [[Arma Reforger:Scripting: Automatic Reference Counting|Automatic Reference Counting]] for more information. | ||
|} | |} | ||
Line 361: | Line 387: | ||
== Code Keywords == | == Code Keywords == | ||
{| class="wikitable" | {| class="wikitable valign-top" | ||
|- | ! Keyword | ||
! Description | |||
|- | |||
! | |||
=== auto === | |||
| Guess the type of the variable. Its usage is '''not''' recommended (see {{Link|Arma Reforger:Scripting: Best Practices|Best Practices}})! | |||
<enforce> | |||
auto myVar = 5; // understood as int myVar = 5 | |||
// but it may have been meant as: | |||
float myVar = 5; | |||
</enforce> | |||
|- | |||
! | ! | ||
=== new === | === new === | ||
| Creates an instance of the provided class. | | Creates an instance of the provided class. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
} | } | ||
ExampleClass classInstance = new ExampleClass(); | ExampleClass classInstance = new ExampleClass(); | ||
</ | </enforce> | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 381: | Line 419: | ||
} | } | ||
} | } | ||
ExampleClass classInstance = new ExampleClass(5); // needs Constructor-defined arguments | ExampleClass classInstance = new ExampleClass(5); // needs Constructor-defined arguments | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== delete === | === delete === | ||
| Deletes an object and sets all its references to {{hl|null}}. | | Deletes an object and sets all its references to {{hl|null}}. | ||
{{Feature|important|It is not possible to delete an object if there is an external reference to it, like an array.}} | {{Feature|important|It is not possible to delete an object if there is an external reference to it, like an array.}} | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 416: | Line 454: | ||
delete obj; // throws a VM Exception | delete obj; // throws a VM Exception | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== thread === | === thread === | ||
| Creates a thread | | Creates a script thread from a method. | ||
{{Feature|important| | |||
* {{hl|thread}} is to be used in {{GameCategory|armaR|Modding|Official Tools|text= Workbench}} plugins. In game, use the <enforce inline>GetGame().GetCallQueue().CallLater()</enforce> method. | |||
* A script thread is not a real thread and member variables are therefore "thread-safe". | |||
}} | |||
<enforce> | |||
class ExampleClass | |||
{ | |||
// calling this method will print | |||
// "MainMethod start" | |||
// "ThreadMethod start", | |||
// "MainMethod end" | |||
// then 500ms later, "ThreadMethod end" | |||
void MainMethod() | |||
{ | |||
Print("MainMethod start"); | |||
thread ThreadMethod(); | |||
Print("MainMethod end"); | |||
} | |||
protected void ThreadMethod() | |||
{ | |||
Print("ThreadMethod start"); | |||
Sleep(500); | |||
Print("ThreadMethod end"); | |||
} | |||
} | |||
</enforce> | |||
; Thread methods are only possible within a threaded method<nowiki>:</nowiki> | |||
* {{hl|Sleep}} takes an integer and waits for the provided amount of milliseconds | |||
* {{hl|Wait}} takes a bool condition and holds until the provided condition is true | |||
|- | |||
! | ! | ||
=== null === | === null === | ||
| A null value. | | A null value. | ||
|- | |- | ||
! | ! | ||
=== this === | === this === | ||
| Refers to the method's object itself. | | Refers to the method's object itself. | ||
< | <enforce> | ||
class ExampleClass | class ExampleClass | ||
{ | { | ||
Line 444: | Line 512: | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
| | |||
Since {{GVI|armaR|1.1.0}}, {{hl|this}} is supported in static methods and behaves like the current type. | |||
<enforce> | |||
class Gen1 | |||
{ | |||
static void DoSmth() { Print("A"); } | |||
} | |||
class Gen2 : Gen1 | |||
{ | |||
static override void DoSmth(Widget utility) | |||
{ | |||
Print("B"); | |||
Print(this); // > Gen2 | |||
} | |||
} | |||
</enforce> | |||
|- | |||
! | ! | ||
=== super === | === super === | ||
| Refers to the '''parent''' class for the requested variable/ | | Refers to the '''parent''' class for the requested variable/method. | ||
< | <enforce> | ||
class Gen1 | class Gen1 | ||
{ | { | ||
Line 460: | Line 545: | ||
class Gen2 : Gen1 | class Gen2 : Gen1 | ||
{ | { | ||
void Method() | override void Method() | ||
{ | { | ||
Print("Gen2 method"); | Print("Gen2 method"); | ||
Line 468: | Line 553: | ||
class Gen3 : Gen2 | class Gen3 : Gen2 | ||
{ | { | ||
void Method() | override void Method() | ||
{ | { | ||
super.Method(); // prints "Gen2 method" | super.Method(); // prints "Gen2 method" | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
Since {{GVI|armaR|1.1.0}}, {{hl|super}} is supported in static methods and behaves like a type. | |||
<enforce> | |||
class Gen1 | |||
{ | |||
static int a = 33; | |||
int b = 42; | |||
static void ShowMessage() { Print("A"); } | |||
} | |||
class Gen2 : Gen1 | |||
{ | |||
static override void ShowMessage(Widget utility) | |||
{ | |||
Print("B"); | |||
Print(super); // > Gen1 | |||
Print(super.a); // > a = 33 | |||
// Print(super.b); <- error - not a static property | |||
super.ShowMessage(); // > "A" | |||
} | |||
} | |||
</enforce> | |||
|- | |||
! | |||
{{ArgTitle|3|vanilla|{{GVI|armaR|1.1.0}}}} | |||
| Refers to the '''unmodded''' version of the modded variable/method. | |||
<enforce> | |||
class ClassA | |||
{ | |||
static void Hello() | |||
{ | |||
Print("vanilla"); | |||
} | |||
} | |||
// mod 1 content | |||
modded class ClassA | |||
{ | |||
override static void Hello() | |||
{ | |||
Print("modded 1"); | |||
} | |||
} | |||
// mod 2 content | |||
modded class ClassA | |||
{ | |||
override static void Hello() | |||
{ | |||
super.Hello(); | |||
vanilla.Hello(); | |||
Print("modded 2"); | |||
} | |||
} | |||
void Test() | |||
{ | |||
ClassA o = new ClassA(); | |||
o.Hello(); // prints modded 1, vanilla, modded 2 | |||
} | |||
</enforce> | |||
|- | |||
| | |||
=== debug === | |||
| Triggers a breakpoint in {{Link|Arma Reforger:Script Editor}}. | |||
{{Feature|informative|This keyword is currently not highlighted as such in Script Editor.}} | |||
<enforce> | |||
class MyClass | |||
{ | |||
[Attribute(defvalue: "0", desc: "Use breakpoints in Workbench")] | |||
protected bool m_bUseBreakpoints; | |||
static void Hello() | |||
{ | |||
Print("This is debugging"); | |||
#ifdef WORKBENCH | |||
if (m_bUseBreakpoints) | |||
debug; | |||
#endif // WORKBENCH | |||
} | |||
} | |||
</enforce> | |||
|} | |} | ||
Line 479: | Line 648: | ||
== Code Flow Keywords == | == Code Flow Keywords == | ||
{| class="wikitable" | {| class="wikitable valign-top" | ||
|- | ! Keyword | ||
! Description | |||
|- | |||
! | ! | ||
=== if === | === if === | ||
| verifies a boolean condition. If the condition is true then the code is executed. | | verifies a boolean condition. If the condition is true then the code is executed. | ||
< | <enforce> | ||
void Method(int value = 0) | void Method(int value = 0) | ||
{ | { | ||
if (value > 50) | if (value > 50) | ||
Print("value is > 50"); | Print("value is > 50"); | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== else === | === else === | ||
| optional, declares code to be executed if the if condition is not met | | optional, declares code to be executed if the if condition is not met | ||
< | <enforce> | ||
void Method(int value = 0) | void Method(int value = 0) | ||
{ | { | ||
if (value > 50) | if (value > 50) | ||
Print("value is > 50"); | Print("value is > 50"); | ||
else | else | ||
Print("value is <= 50"); | Print("value is <= 50"); | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== for === | === for === | ||
| processes code while the provided condition is met. The syntax is: | | processes code while the provided condition is met. The syntax is: | ||
< | <enforce> | ||
for (initialisation; loopCondition; completionCode) | for (initialisation; loopCondition; completionCode) | ||
{ | { | ||
// code here | // code here | ||
} | } | ||
</ | </enforce> | ||
< | <enforce> | ||
void MethodA(notnull array<string> words) | void MethodA(notnull array<string> words) | ||
{ | { | ||
for (int i = 0; i < words.Count(); i++) | // for (int i = 0; i < words.Count(); i++) // this if for example's sake; use '''foreach''' instead | ||
for (int i, count = words.Count(); i < count; ++i) // optimised | |||
{ | { | ||
Print(words[i]); | Print(words[i]); | ||
Line 531: | Line 697: | ||
void MethodB(notnull array<string> words) | void MethodB(notnull array<string> words) | ||
{ | { | ||
int i = | int i; // auto-initialised to zero | ||
for (; i < | int count = words.Count(); | ||
for (; i < count; i++) // initialisation is optional | |||
{ | { | ||
Print(words[i]); | Print(words[i]); | ||
Line 540: | Line 707: | ||
void MethodC(notnull array<string> words) | void MethodC(notnull array<string> words) | ||
{ | { | ||
for (int i = | for (int i, count = words.Count(); i < count;) // so is completionCode | ||
{ | { | ||
Print(words[i]); | Print(words[i]); | ||
i++; | i++; // do not forget it! | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== foreach === | === foreach === | ||
| processes code for each element of an iterable object (e.g an array). Iteration separator is{{hl|:}}. | | processes code for each element of an iterable object (e.g an array). Iteration separator is{{hl|:}}. | ||
< | <enforce> | ||
// array example | // array example | ||
void Method(notnull array<string> words) | void Method(notnull array<string> words) | ||
Line 560: | Line 727: | ||
} | } | ||
foreach (string word | foreach (int index, string word : words) | ||
{ | { | ||
PrintFormat("word #%1 is %2", index, word); | PrintFormat("word #%1 is %2", index, word); | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
< | <enforce> | ||
// map example | // map example | ||
void Method(notnull map<string, int> data) | void Method(notnull map<string, int> data) | ||
Line 575: | Line 742: | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== while === | === while === | ||
| processes code while condition is met. Beware, as it can lock the program on wrong conditions! | | processes code while condition is met. Beware, as it can lock the program on wrong conditions! | ||
< | <enforce> | ||
void Method(array<string> words) | void Method(array<string> words) | ||
{ | { | ||
Line 590: | Line 757: | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
! | ! | ||
=== switch === | === switch === | ||
| switches the code to execute depending on the condition | | switches the code to execute depending on the condition | ||
< | <enforce> | ||
void Method(string word) | void Method(string word) | ||
{ | { | ||
Line 613: | Line 780: | ||
} | } | ||
} | } | ||
</ | </enforce> | ||
|- | |- | ||
| | |||
=== continue === | |||
| Used to skip to the next iteration in {{hl|for}}, {{hl|foreach}}, {{hl|while}} loops | |||
<enforce> | |||
class ExampleClass | |||
{ | |||
// this method will print 0, 1, 2, 4 | |||
void Skip3() | |||
{ | |||
for (int i; i < 5; i++) | |||
{ | |||
if (i == 3) | |||
continue; | |||
Print(i.ToString()); | |||
} | |||
} | |||
void MethodB() | |||
{ | |||
foreach (IEntity entity : m_aEntities) | |||
{ | |||
if (!entity) | |||
continue; | |||
Print(entity); | |||
} | |||
} | |||
} | |||
</enforce> | |||
|- | |||
! | ! | ||
=== return === | === return === | ||
| | | Exits the method immediately with the provided value if any. | ||
<enforce> | |||
class ExampleClass | |||
{ | |||
void PrintHelloThere(bool print) | |||
{ | |||
if (!print) | |||
return; // ends here if print is false | |||
Print("Hello there"); | |||
} | |||
float GetDistanceNotZero(vector v1, vector v2) | |||
{ | |||
if (v1 == v2) | |||
return -1; | |||
return vector.Distance(v1, v2); | |||
} | |||
} | |||
</enforce> | |||
|} | |} | ||
{{GameCategory|armaR|Modding|Guidelines|Scripting}} | {{GameCategory|armaR|Modding|Guidelines|Scripting}} |
Latest revision as of 13:55, 27 June 2024
Contents
Class Keywords
Keyword | Description |
---|---|
class |
Declares a class
class ExampleClass
{
} |
modded |
See Object Oriented Programming Advanced Usage - Modding.
class ExampleClass
{
}
modded class ExampleClass // inherits and "takes the place" of the original ExampleClass
{
} |
sealed |
A class marked with the sealed keyword cannot be inherited from
sealed class Infertile
{
}
class Child : Infertile // compilation error - a class cannot inherit from a sealed class
{
} |
extends |
states that the declared class inherits from another
class ChildClass extends ParentClass
{
}
// alias
class ChildClass : ParentClass
{
} |
typedef |
Declares an alias for a type
|
Method Keywords
Keyword | Description |
---|---|
proto |
Disclose an engine-side method to script (Engine side). |
external |
Compiler hint to link API methods - only applies to proto methods (Engine side). |
native |
Native call convention of internal method (Engine side). |
volatile |
Internal method that may call back to script (hint for compiler that context need to be saved on stack). |
private |
Modifier for class method. The method can be called only from inside of the same class' methods. A modded class will not be able to use it either.
class ExampleClass
{
private void HelloWorld()
{
Print("Hello there");
}
void PublicHelloWorld()
{
HelloWorld(); // works from within the object
}
}
ExampleClass classInstance = new ExampleClass();
classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld()
classInstance.HelloWorld(); // compilation error - HelloWorld() is private and cannot be accessed |
protected |
Modifier for class method. The method can be called only from inside of class' methods or methods of its extended (children) classes, or a modded class.
class ParentClass
{
protected void HelloWorld()
{
Print("Hello there");
}
}
class ChildClass : ParentClass
{
void PublicHelloWorld()
{
HelloWorld(); // works from within the object
}
}
ChildClass classInstance = new ChildClass();
classInstance.PublicHelloWorld(); // works - calls PublicHelloWorld() that calls HelloWorld()
classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed
ParentClass classInstance = new ParentClass();
classInstance.HelloWorld(); // compilation error - HelloWorld() is protected and cannot be accessed |
static |
Modifier for class method. The method can be called without object pointer, just by ClassName.methodName(). Only static values/methods can be accessed from a static method.
class ExampleClass
{
static void HelloWorld()
{
Print("Hello there");
}
}
ExampleClass.HelloWorld(); // works
ExampleClass classInstance = new ExampleClass();
classInstance.HelloWorld(); // works |
event |
Hint for tools that the method should be exposed as Entity script event. |
override |
Modifier for class method indicating overriding of base class method. Compiler checks if is method present in base class and if method signature matches.
class ParentClass
{
void HelloWorld()
{
Print("Hello world");
}
}
class ChildClass : ParentClass
{
override void HelloWorld()
{
Print("Hello there");
}
}
ParentClass parentClassInstance = new ParentClass();
parentClassInstance.HelloWorld(); // prints "Hello world"
ChildClass childClassInstance = new ChildClass();
childClassInstance.HelloWorld(); // prints "Hello there" |
sealed |
Modifier for class method. The method cannot be overridden in derived classes.
class ParentClass
{
sealed void HelloWorld()
{
Print("Hello there");
}
}
class ChildClass : ParentClass
{
override void HelloWorld() // compilation error - cannot override a sealed method
{
Print("Hello world");
}
} |
Value Keywords
Keyword | Description |
---|---|
owned |
Modifier for returning internal methods. Tells the script VM that the returning variable (string or array) must not be released. |
out |
Modifier for method parameters. It means that the argument may be changed by the method call. |
inout |
Modifier for method parameters. It means that the argument will be used and may be changed by the method call.
class ExampleClass
{
private ref array<string> m_aOldParameter;
void Method(inout array<string> parameter)
{
m_aOldParameter = parameter;
parameter = {};
parameter.Insert("Hello");
parameter.Insert("there");
}
}
ExampleClass classInstance = new ExampleClass();
array<string> myArray = null;
classInstance.Method(myArray); // myArray is now { "Hello", "there" } and classInstance.m_aList is referencing myArray's old value |
const |
Declares a constant, that is a value that cannot be modified later.
const string MY_TEXT = "Hello there";
void Method1()
{
Print(MY_TEXT); // will print "Hello there"
MY_TEXT = "General Kenobi"; // compilation error - a constant is set in stone and cannot be modified
}
void Method2()
{
const string myUnmodifiableString = "Hello there"; // constant valid for method's scope
Print(myUnmodifiableString);
myUnmodifiableString = "General Kenobi"; // compilation error
} |
reference |
Hint for tools (Material editor) that the value may be used as parameter in material. |
notnull |
Modifier for method parameter of class pointer type. It means that the method expect the parameter to never be null; if a null value is provided, a VM Exception is raised and the method is not called.
void Method(notnull IEntity entity) // no need to check for "if (!entity)" inside the method
{
entity.DoSomething(); // the argument can be accessed safely
}
if (myEntity) // it is still needed to check for null before calling the method
{
Method(myEntity);
} |
private |
Value can only be accessed from the class/instance methods. Mutually exclusive with "protected". |
protected |
Value can only be accessed from the class/instance methods or its children. Mutually exclusive with "private".
class ParentClass
{
protected bool m_bProtected;
private bool m_bPrivate;
void SetPrivate(bool value)
{
m_bPrivate = value;
}
}
class ChildClass : ParentClass
{
void SetProtected(bool value)
{
m_bProtected = value; // works - m_bProtected declaration reaches ChildClass
}
}
ChildClass childClassInstance = new ChildClass();
Print(childClassInstance.m_bProtected); // compilation error - m_bProtected is protected and cannot be accessed |
static |
Value belongs to the class and not an instance of it. If public, it can be accessed without object pointer, just by ClassName.variable class ExampleClass
{
static bool bStaticValue;
private static bool m_bPrivate; // it is good practice to make it protected/private and have getters/setters instead
}
Print(ExampleClass.bStaticValue); // works
ExampleClass.bStaticValue = true; // works
ExampleClass classInstance = new ExampleClass();
Print(classInstance.bStaticValue); // works
classInstance.bStaticValue = true; // works |
autoptr |
Modifier for class/pointer values. Pointed object will be automatically destroyed upon end of variable lifetime (end of scope, or deletion of class, that contain it). |
ref |
Strong reference. See Automatic Reference Counting for more information. |
Code Keywords
Keyword | Description |
---|---|
auto |
Guess the type of the variable. Its usage is not recommended (see Best Practices)!
|
new |
Creates an instance of the provided class.
class ExampleClass
{
}
ExampleClass classInstance = new ExampleClass(); class ExampleClass
{
void ExampleClass(int myValue) // a method named from the class is the constructor
{
Print(myValue);
}
}
ExampleClass classInstance = new ExampleClass(5); // needs Constructor-defined arguments |
delete |
Deletes an object and sets all its references to null.
class ExampleClass
{
void Method()
{
ReferencedClass obj;
if (!obj)
Print("obj is null");
obj = new ReferencedClass();
if (obj)
Print("obj is not null");
delete obj;
if (!obj)
Print("obj is null");
// everything was fine
obj = new ReferencedClass();
if (obj)
Print("obj is not null");
array<ref ReferencedClass> list = {};
list.Insert(obj);
delete obj; // throws a VM Exception
}
} |
thread |
Creates a script thread from a method.
class ExampleClass
{
// calling this method will print
// "MainMethod start"
// "ThreadMethod start",
// "MainMethod end"
// then 500ms later, "ThreadMethod end"
void MainMethod()
{
Print("MainMethod start");
thread ThreadMethod();
Print("MainMethod end");
}
protected void ThreadMethod()
{
Print("ThreadMethod start");
Sleep(500);
Print("ThreadMethod end");
}
}
|
null |
A null value. |
this |
Refers to the method's object itself.
class ExampleClass
{
void MethodA()
{
this.MethodB();
}
void MethodB()
{
Print("It works");
}
} Since 1.1.0, this is supported in static methods and behaves like the current type. class Gen1
{
static void DoSmth() { Print("A"); }
}
class Gen2 : Gen1
{
static override void DoSmth(Widget utility)
{
Print("B");
Print(this); // > Gen2
}
} |
super |
Refers to the parent class for the requested variable/method.
class Gen1
{
void Method()
{
Print("Gen1 method");
}
}
class Gen2 : Gen1
{
override void Method()
{
Print("Gen2 method");
}
}
class Gen3 : Gen2
{
override void Method()
{
super.Method(); // prints "Gen2 method"
}
} Since 1.1.0, super is supported in static methods and behaves like a type. class Gen1
{
static int a = 33;
int b = 42;
static void ShowMessage() { Print("A"); }
}
class Gen2 : Gen1
{
static override void ShowMessage(Widget utility)
{
Print("B");
Print(super); // > Gen1
Print(super.a); // > a = 33
// Print(super.b); <- error - not a static property
super.ShowMessage(); // > "A"
}
} |
vanilla |
Refers to the unmodded version of the modded variable/method.
class ClassA
{
static void Hello()
{
Print("vanilla");
}
}
// mod 1 content
modded class ClassA
{
override static void Hello()
{
Print("modded 1");
}
}
// mod 2 content
modded class ClassA
{
override static void Hello()
{
super.Hello();
vanilla.Hello();
Print("modded 2");
}
}
void Test()
{
ClassA o = new ClassA();
o.Hello(); // prints modded 1, vanilla, modded 2
} |
debug |
Triggers a breakpoint in Script Editor.
class MyClass
{
[Attribute(defvalue: "0", desc: "Use breakpoints in Workbench")]
protected bool m_bUseBreakpoints;
static void Hello()
{
Print("This is debugging");
#ifdef WORKBENCH
if (m_bUseBreakpoints)
debug;
#endif // WORKBENCH
}
} |
Code Flow Keywords
Keyword | Description |
---|---|
if |
verifies a boolean condition. If the condition is true then the code is executed.
|
else |
optional, declares code to be executed if the if condition is not met
void Method(int value = 0)
{
if (value > 50)
Print("value is > 50");
else
Print("value is <= 50");
} |
for |
processes code while the provided condition is met. The syntax is:
for (initialisation; loopCondition; completionCode)
{
// code here
} void MethodA(notnull array<string> words)
{
// for (int i = 0; i < words.Count(); i++) // this if for example's sake; use foreach instead
for (int i, count = words.Count(); i < count; ++i) // optimised
{
Print(words[i]);
}
}
void MethodB(notnull array<string> words)
{
int i; // auto-initialised to zero
int count = words.Count();
for (; i < count; i++) // initialisation is optional
{
Print(words[i]);
}
}
void MethodC(notnull array<string> words)
{
for (int i, count = words.Count(); i < count;) // so is completionCode
{
Print(words[i]);
i++; // do not forget it!
}
} |
foreach |
processes code for each element of an iterable object (e.g an array). Iteration separator is:.
|
while |
processes code while condition is met. Beware, as it can lock the program on wrong conditions! |
switch |
switches the code to execute depending on the condition
void Method(string word)
{
switch (word)
{
case "Hello":
Print("it's Hello");
break;
case "there":
Print("it's there");
break;
default:
Print("it's not interesting.");
break;
}
} |
continue |
Used to skip to the next iteration in for, foreach, while loops |
return |
Exits the method immediately with the provided value if any. |