GM Version: Studio 2.3+
Target Platform: Windows / All
Download: n/a
Links: n/a
[PROBLEM]
Today we will be talking about static variables initialization order... now you might ask:
[EXPLANATION]
So
[TEXT TUTORIAL] Keyword "static" Explained
Regarding execution order there are two rules to take into consideration:
Now that we have the basics lets look at some code.
(1) INITIAL SETUP
One of the places where we can experience the execution order and probably the most common one is inside constructor functions.
The example above can look a little bit strange but believe me, it has its purpose.
(2) EXECUTION ORDER
I will now number the order in which lines get executed:
So as you can see
(3) A LITTLE TIP
So when working with static always imagine you are pulling the static variables to start of the function/constructor, like so:
(4) IMPLICATIONS + INHERITANCE
So what are the implications of this?
Though this doesn't look like a big deal it is when you start using inheritance, for example:
Before going any further, go ahead and try to find out what is the output of the above code.
I will wait...
For those who didn't manager to follow I will again number the line execution.
Here is what happens when you create the instance of
(5) OVERRIDING
In the example above I introduced the concept of override this concept consists into changing the value of some function/variable inside a child constructor.
So a good practice when you want to override a function is using the following:
It is important to note one thing, in execution line (2) when I store the old function reference, I use a
[CONCLUSION]
And that's it, static keyword declarations are executed before every other line of code in a given scope.
And though this can allow for a lot of cool stuff it also needs attention.
That was quite a lot of information and a lot of examples so remember to go through it a couple of times to understand it well.
Here xD from xDGameStudios,
Good coding to you all.
Target Platform: Windows / All
Download: n/a
Links: n/a
[PROBLEM]
Today we will be talking about static variables initialization order... now you might ask:
"What? Is there a special order for static variables?"
[EXPLANATION]
So
static
keyword again! If you don't know what it is you should first take a look at my first tutorial on the subject:[TEXT TUTORIAL] Keyword "static" Explained
Regarding execution order there are two rules to take into consideration:
- static declarations in a given scope occur before everything else.
- among themselves static declarations occur in the order they appear in the code.
Now that we have the basics lets look at some code.
(1) INITIAL SETUP
One of the places where we can experience the execution order and probably the most common one is inside constructor functions.
GML:
function MyConstructor() constructor {
static staticReal = 10;
instanceReal = 1;
static staticString = "Hello";
instanceFunc = function() {}
static staticFunc = function() {}
}
(2) EXECUTION ORDER
I will now number the order in which lines get executed:
GML:
function MyConstructor() constructor {
static staticReal = 10; // (1)
instanceReal = 1; // (4)
static staticString = "Hello"; // (2)
instanceFunc = function() {} // (5)
static staticFunc = function() {} // (3)
}
static
variables declarations are executed before the rest of the code.(3) A LITTLE TIP
So when working with static always imagine you are pulling the static variables to start of the function/constructor, like so:
GML:
function MyConstructor() constructor {
static staticReal = 10; // (1)
static staticString = "Hello"; // (2)
static staticFunc = function() {} // (3)
instanceReal = 1; // (4)
instanceFunc = function() {} // (5)
}
(4) IMPLICATIONS + INHERITANCE
So what are the implications of this?
GML:
function MyConstructor() constructor {
show_debug_message(staticReal); // (2) Even though 'staticReal' definition is placed below this does NOT throw an error.
static staticReal = 10; // (1)
show_debug_message(instanceReal) // (3) [ERROR] with non-static the execution flow is normal.
instanceReal = 1; // (4)
}
GML:
function MyParentConstructor() constructor {
print();
static value = 10;
static print = function() {
show_debug_message(value);
}
print();
}
function MyChildConstructor() : MyParentConstructor() constructor {
print();
static value = "hello"
static print = function() {
show_debug_message(value + " world");
}
print();
}
var _instance = new MyChildConstructor();
I will wait...
10
10
hello world
hello world
10
hello world
hello world
For those who didn't manager to follow I will again number the line execution.
Here is what happens when you create the instance of
MyChildConstructor
GML:
function MyParentConstructor() constructor {
print(); // (3) This is the first print -> 10
static value = 10; // (1) This is the first one because parent code is execute before child code
static print = function() { // (2)
show_debug_message(value);
}
print(); // (4) This is the second print -> 10
}
function MyChildConstructor() : MyParentClass() constructor {
print(); // (7) This is the third print -> "hello world"
static value = "hello" // (5)
static print = function() { // (6) this is overriding the parent function
show_debug_message(value + " world");
}
print(); // (8) This is the fourth print -> "hello world"
}
(5) OVERRIDING
In the example above I introduced the concept of override this concept consists into changing the value of some function/variable inside a child constructor.
So a good practice when you want to override a function is using the following:
GML:
function MyParentConstructor() constructor {
static print = function() { // (1) This function is declared
show_debug_message("Hello");
}
}
function MyChildConstructor() : MyParentClass() constructor {
static print_MyParentClass = print; // (2) Here I store the old function in a new static variable (OPTIONAL)
static print = function() { // (3) Now I redeclared the print function
print_MyParentClass(); // As I stored the old declaration (2) I can still call it here.
show_debug_message("World");
}
}
var _instance = new MyChildConstructor();
_instance.print();
// Hello
// World
static
variable and this is actually a MUST otherwise you would end with the code:
GML:
function MyParentConstructor() constructor {
static print = function() { // (1) This function is declared
show_debug_message("Hello");
}
}
function MyChildConstructor() : MyParentClass() constructor {
print_MyParentClass = print; // (3) This line now is executed after
static print = function() { // (2) Now I redeclared the print function
print_MyParentClass(); // As we didn't use static print_MyParentClass points to the child's definition (this function)
show_debug_message("World");
}
}
var _instance = new MyChildConstructor();
_instance.print(); // This will hang execution as the function will enter in a recursive loop.
[CONCLUSION]
And that's it, static keyword declarations are executed before every other line of code in a given scope.
And though this can allow for a lot of cool stuff it also needs attention.
That was quite a lot of information and a lot of examples so remember to go through it a couple of times to understand it well.
Here xD from xDGameStudios,
Good coding to you all.
Last edited: