Closed
Description
Description
I found a strange behavior of the execution context in a script.
The following example works fine when it is executed directly in squirrel 3.1, but it fails when it is executed in the game with the following message AN ERROR HAS OCCURRED [the index 'Point' does not exist]
Steps to reproduce
Steps to reproduce the strange behavior:
- Have a .nut script that has the following code:
class Point {
x = null;
y = null;
constructor(_x, _y) {
x = _x;
y = _y;
}
}
class Rectangle {
topLeftPoint = null;
bottomRightPoint = null;
constructor() {
topLeftPoint = Point(0, 0);
bottomRightPoint = Point(100, 100);
}
}
rectangle <- Rectangle();
- Craete a map that references our script by logic_script entity and run the map.
- See the following error in the console AN ERROR HAS OCCURRED [the index 'Point' does not exist]
Expected behavior
The expected behavior is to run the map and the Rectangle class is successfully instantiated.
Additional context, that may help for better understanding the problem
After hours of reading, debugging and testing I reproduce the same error in pure squirrel (v3.1), and it looks like the core of the problem should be in the execution context.
- Reproduced in Squirrel v3.1 - Nested execution context
CustomScope <- {}
class CustomScope.Point {}
class CustomScope.Circle {
position = null;
constructor() {
// Here the Point does not exists either in current environment (this) and root table(::).
// It exists ony in the CustomScope table
position = Point(0, 0);
}
}
function CustomScope::Run() {
// Here the Point and Circle exists, because the current environment(this) is the CustomScope.
local point = Point();
local circle = Circle();
}
CustomScope.Run();
- Reproduced in Squirrel v3.1 - Execute a file in nested execution context
## execution code
CustomScope <- {}
function CustomScope::Run() {
dofile("file-to-include.nut"); // load, compile and execute a code in the CustomScpoe execution context
}
CustomScope.Run();
## file-to-include.nut
class Point {}
class Circle {
position = null;
constructor() {
// Here the Point does not exists either in current environment (this) and root table(::).
// It exists ony in the CustomScope table
position = Point(0, 0);
}
}
// Here the Point and Circle exists, because the current environment(this) is the CustomScope.
local point = Point();
local circle = Circle();
- Tested in Mapbase VScript - Workaround for the issue
// define the script's scope in the root table, in order to access it in any execution context
::MyScriptScope <- this;
class Point {
x = null;
y = null;
constructor(_x, _y) {
x = _x;
y = _y;
}
}
class Rectangle {
topLeftPoint = null;
bottomRightPoint = null;
constructor() {
// access the Point class by accessing the MyScriptScope, which is defined in the root table
topLeftPoint = ::MyScriptScope.Point(0, 0);
bottomRightPoint = ::MyScriptScope.Point(100, 100);
}
}
rectangle <- Rectangle();
printl(rectangle);