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

From Bohemia Interactive Community
Jump to navigation Jump to search
m (1 revision imported)
m (Some wiki formatting)
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Feature|important|Follow [[Arma Reforger:Scripting: Conventions]].}}
{| class="wikitable" style="width: 100%"
{| class="wikitable" style="width: 100%"
|+ {{Feature|important|Do follow {{Link|Arma Reforger:Scripting: Conventions|Scripting Conventions}}.}}
! style="width: 50%" | Don't
! style="width: 50%" | Don't
! style="width: 50%" | Do
! style="width: 50%" | Do
|- style="vertical-align: top"
|- style="vertical-align: top"
|
|
<syntaxhighlight lang="c#">
<enforce noGuess>
class ExampleClass {
class ExampleClass {
   int LProcLgh;
   int LProcLgh;
Line 16: Line 15:
}
}
}
}
</syntaxhighlight>
</enforce>
|
|
<syntaxhighlight lang="c#">
<enforce>
class ExampleClass
class ExampleClass
{
{
Line 35: Line 34:
}
}
}
}
</syntaxhighlight>
</enforce>
|}
|}


Keep variables as close as possible to their usage:
{| class="wikitable" style="width: 100%"
{| class="wikitable" style="width: 100%"
|+ {{Feature|important|Keep variables as close as possible to their usage.}}
! style="width: 50%" | Don't
! style="width: 50%" | Don't
! style="width: 50%" | Do
! style="width: 50%" | Do
|- style="vertical-align: top"
|- style="vertical-align: top"
|
|
<syntaxhighlight lang="c#">
<enforce>
class ExampleClass
class ExampleClass
{
{
Line 56: Line 55:
}
}
}
}
</syntaxhighlight>
</enforce>
|
|
<syntaxhighlight lang="c#">
<enforce>
class ExampleClass
class ExampleClass
{
{
Line 70: Line 69:
}
}
}
}
</syntaxhighlight>
</enforce>
|}
|}


Keep a strong reference (<tt>ref</tt> keyword) to required objects:
{| class="wikitable" style="width: 100%"
{| class="wikitable" style="width: 100%"
|+ {{Feature|important|Keep a strong reference (<enforce inline>ref</enforce> keyword) to required objects.}}
! style="width: 50%" | Don't
! style="width: 50%" | Don't
! style="width: 50%" | Do
! style="width: 50%" | Do
|- style="vertical-align: top"
|- style="vertical-align: top"
|
|
<syntaxhighlight lang="c#">
<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 = new array<ExampleClass>();
Line 90: Line 89:
// as there are no references to it
// as there are no references to it
}
}
</syntaxhighlight>
</enforce>
|
|
<syntaxhighlight lang="c#">
<enforce>
// this array keeps strong references to its items
// this array keeps strong references to its items
array<ref ExampleClass> classArray = new array<ref ExampleClass>();
array<ref ExampleClass> classArray = new array<ref ExampleClass>();
Line 102: Line 101:
// classArray keeps a strong reference to newInstance - it will not be cleared
// classArray keeps a strong reference to newInstance - it will not be cleared
}
}
</syntaxhighlight>
</enforce>
|}
|}


Avoid strong reference cyclic trap:
{| class="wikitable" style="width: 100%"
{| class="wikitable" style="width: 100%"
|+ {{Feature|important|Avoid strong reference cyclic trap.}}
! style="width: 50%" | Don't
! style="width: 50%" | Don't
! style="width: 50%" | Do
! style="width: 50%" | Do
|- style="vertical-align: top"
|- style="vertical-align: top"
| {{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 [[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 [[Arma Reforger:Scripting: Automatic Reference Counting]] for more information).}}
<syntaxhighlight lang="c#">
<enforce>
class MainClass
class MainClass
{
{
ref SubClass m_subClass;
ref SubClass m_SubClass;
   
   
void MainClass()
void MainClass()
{
{
m_subClass = new SubClass(this);
m_SubClass = new SubClass(this);
}
}
}
}
Line 124: Line 123:
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()
{
{
Print(m_parent);
Print(m_Parent);
}
}
}
}
</syntaxhighlight>
</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 doesn't exist, it will simply not use it.}}
<syntaxhighlight lang="c#">
<enforce>
class MainClass
class MainClass
{
{
ref SubClass m_subClass;
ref SubClass m_SubClass;
   
   
void MainClass()
void MainClass()
{
{
m_subClass = new SubClass(this);
m_SubClass = new SubClass(this);
}
}
}
}
Line 151: Line 150:
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()
{
{
if (!m_parent) // null safety check
if (!m_Parent) // null safety check
{
return;
return;
}
 
Print(m_parent);
Print(m_Parent);
}
}
}
}
</syntaxhighlight>
</enforce>
|}
|}


Line 180: Line 178:
|- style="vertical-align: top"
|- style="vertical-align: top"
|
|
<syntaxhighlight lang="c#">
<enforce>


</syntaxhighlight>
</enforce>
|
|
<syntaxhighlight lang="c#">
<enforce>


</syntaxhighlight>
</enforce>
|}
|}
-->
-->

Revision as of 02:11, 17 June 2023

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; } }

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 = new array<ExampleClass>(); for (int i = 0; i < 10; i++) { ExampleClass 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 strong references to its items array<ref ExampleClass> classArray = new array<ref ExampleClass>(); for (int i = 0; i < 10; i++) { ExampleClass 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 Arma Reforger: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 doesn't 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); } }