Scripting: Do's and Don'ts – Arma Reforger

From Bohemia Interactive Community
Jump to navigation Jump to search
(Add switch scopes info)
m (Some wiki formatting)
 
Line 21: Line 21:
{
{
protected int m_iLastProcessedLength;
protected int m_iLastProcessedLength;
 
int GetStringLength(string value)
int GetStringLength(string value)
{
{
Line 28: Line 28:
return m_iLastProcessedLength;
return m_iLastProcessedLength;
}
}
 
int GetLastProcessedLength()
int GetLastProcessedLength()
{
{
Line 47: Line 47:
{
{
protected int m_iLength;
protected int m_iLength;
 
int GetStringLength(string name)
int GetStringLength(string name)
{
{
Line 61: Line 61:
{
{
// keeping the variable into method scope and away from the instance
// keeping the variable into method scope and away from the instance
 
int GetStringLength(string name)
int GetStringLength(string name)
{
{
Line 120: Line 120:
<enforce>
<enforce>
// this array only lists pointers but does not increase the reference count
// this array only lists pointers but does not increase the reference count
array<ExampleClass> classArray = new array<ExampleClass>();
array<ExampleClass> classArray = {};
 
for (int i = 0; i < 10; i++)
ExampleClass newInstance;
for (int i; i < 10; i++)
{
{
ExampleClass newInstance = new ExampleClass();
newInstance = new ExampleClass();
classArray.Insert(newInstance);
classArray.Insert(newInstance);
// newInstance will be deleted at the end of the scope
// newInstance will be deleted at the end of the scope
Line 132: Line 133:
|
|
<enforce>
<enforce>
// this array keeps strong references to its items
// this array keeps a strong reference to its items
array<ref ExampleClass> classArray = new array<ref ExampleClass>();
array<ref ExampleClass> classArray = {};
 
for (int i = 0; i < 10; i++)
ExampleClass newInstance;
for (int i; i < 10; i++)
{
{
ExampleClass newInstance = new ExampleClass();
newInstance = new ExampleClass();
classArray.Insert(newInstance);
classArray.Insert(newInstance);
// classArray keeps a strong reference to newInstance - it will not be cleared
// classArray keeps a strong reference to newInstance - it will not be cleared
Line 149: Line 151:
! style="width: 50%" | Do
! style="width: 50%" | Do
|-
|-
| {{Feature|informative|Here, both ParentClass and ChildClass have a strong reference to each other, keeping the reference count above zero - creating an "island of isolation" (see [[Arma Reforger:Scripting: Automatic Reference Counting]] for more information).}}
| {{Feature|informative|
Here, both ParentClass and ChildClass have a strong reference to each other, keeping the reference count above zero - creating an "island of isolation" (see {{Link|Arma Reforger:Scripting: Automatic Reference Counting}} for more information).
}}
<enforce>
<enforce>
class MainClass
class MainClass
{
{
ref SubClass m_SubClass;
ref SubClass m_SubClass;
 
void MainClass()
void MainClass()
{
{
Line 160: Line 164:
}
}
}
}
 
class SubClass
class SubClass
{
{
ref MainClass m_Parent;
ref MainClass m_Parent;
 
void SubClass(MainClass parent)
void SubClass(MainClass parent)
{
{
m_Parent = parent;
m_Parent = parent;
}
}
 
void DoSomething()
void DoSomething()
{
{
Line 176: Line 180:
}
}
</enforce>
</enforce>
| {{Feature|informative|Here, the MainClass needs the SubClass (it creates it in its constructor meaning it needs it to work) but the subClass does not require MainClass - if the MainClass reference doesn't exist, it will simply not use it.}}
| {{Feature|informative|
Here, the MainClass needs the SubClass (it creates it in its constructor meaning it needs it to work) but the subClass does not require MainClass - if the MainClass reference does not exist, it will simply not use it.
}}
<enforce>
<enforce>
class MainClass
class MainClass
{
{
ref SubClass m_SubClass;
ref SubClass m_SubClass;
 
void MainClass()
void MainClass()
{
{
Line 187: Line 193:
}
}
}
}
 
class SubClass
class SubClass
{
{
MainClass m_Parent; // ref removed
MainClass m_Parent; // ref removed
 
void SubClass(MainClass parent)
void SubClass(MainClass parent)
{
{
m_Parent = parent;
m_Parent = parent;
}
}
 
void DoSomething()
void DoSomething()
{
{

Latest revision as of 11:38, 9 September 2024

Don't Do

class ExampleClass { int LProcLgh; int stringlength( string Value ){ LProcLgh= Value.Length(); Print ( "String length obtained: "+LProcLgh ); return LProcLgh; } }

class ExampleClass { protected int m_iLastProcessedLength; int GetStringLength(string value) { m_iLastProcessedLength = value.Length(); Print("String length obtained: " + m_iLastProcessedLength); return m_iLastProcessedLength; } int GetLastProcessedLength() { return m_iLastProcessedLength; } }

Keep variables as close as possible to their usage.
Don't Do

class ExampleClass { protected int m_iLength; int GetStringLength(string name) { m_iLength = name.Length(); Print("String length obtained: " + m_iLength); return m_iLength; } }

class ExampleClass { // keeping the variable into method scope and away from the instance int GetStringLength(string name) { int length = name.Length(); Print("String length obtained: " + length); return length; } }

Do not scope more than necessary.
Don't Do

switch (value) { case 0: { Print("0"); break; } default: { Print("default"); break; } }

switch (value) { case 0: Print("0"); break; default: // brackets are needed only if variables are declared in the 'case' code { // otherwise scoping is superfluous (and very slightly impacts performance) string message = "default"; Print(message); break; } }

Keep a strong reference (ref keyword) to required objects.
Don't Do

// this array only lists pointers but does not increase the reference count array<ExampleClass> classArray = {}; ExampleClass newInstance; for (int i; i < 10; i++) { newInstance = new ExampleClass(); classArray.Insert(newInstance); // newInstance will be deleted at the end of the scope // as there are no references to it }

// this array keeps a strong reference to its items array<ref ExampleClass> classArray = {}; ExampleClass newInstance; for (int i; i < 10; i++) { newInstance = new ExampleClass(); classArray.Insert(newInstance); // classArray keeps a strong reference to newInstance - it will not be cleared }

Avoid strong reference cyclic trap.
Don't Do
Here, both ParentClass and ChildClass have a strong reference to each other, keeping the reference count above zero - creating an "island of isolation" (see Scripting: Automatic Reference Counting for more information).

class MainClass { ref SubClass m_SubClass; void MainClass() { m_SubClass = new SubClass(this); } } class SubClass { ref MainClass m_Parent; void SubClass(MainClass parent) { m_Parent = parent; } void DoSomething() { Print(m_Parent); } }

Here, the MainClass needs the SubClass (it creates it in its constructor meaning it needs it to work) but the subClass does not require MainClass - if the MainClass reference does not exist, it will simply not use it.

class MainClass { ref SubClass m_SubClass; void MainClass() { m_SubClass = new SubClass(this); } } class SubClass { MainClass m_Parent; // ref removed void SubClass(MainClass parent) { m_Parent = parent; } void DoSomething() { if (!m_Parent) // null safety check return; Print(m_Parent); } }