summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/script_language.h2
-rw-r--r--editor/editor_autoload_settings.cpp164
-rw-r--r--editor/editor_autoload_settings.h2
-rw-r--r--main/main.cpp194
-rw-r--r--modules/gdscript/gdscript.cpp9
-rw-r--r--modules/gdscript/gdscript.h6
-rw-r--r--modules/gdscript/gdscript_compiler.cpp24
-rw-r--r--modules/gdscript/gdscript_compiler.h3
-rw-r--r--modules/gdscript/gdscript_function.cpp15
-rw-r--r--modules/gdscript/gdscript_function.h10
10 files changed, 329 insertions, 100 deletions
diff --git a/core/script_language.h b/core/script_language.h
index 0c1f99cea6..1cd27c07dc 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -236,6 +236,8 @@ public:
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const = 0;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) = 0;
+ virtual void add_named_global_constant(const StringName &p_name, const Variant &p_value) {}
+ virtual void remove_named_global_constant(const StringName &p_name) {}
/* MULTITHREAD FUNCTIONS */
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index a2f5c1aa1a..708bff252a 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -33,6 +33,8 @@
#include "editor_node.h"
#include "global_constants.h"
#include "project_settings.h"
+#include "scene/main/viewport.h"
+#include "scene/resources/packed_scene.h"
#define PREVIEW_LIST_MAX_SIZE 10
@@ -155,8 +157,8 @@ void EditorAutoloadSettings::_autoload_edited() {
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_autoload, order);
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
- undo_redo->add_do_method(this, "update_autoload");
- undo_redo->add_undo_method(this, "update_autoload");
+ undo_redo->add_do_method(this, "call_deferred", "update_autoload");
+ undo_redo->add_undo_method(this, "call_deferred", "update_autoload");
undo_redo->add_do_method(this, "emit_signal", autoload_changed);
undo_redo->add_undo_method(this, "emit_signal", autoload_changed);
@@ -187,8 +189,8 @@ void EditorAutoloadSettings::_autoload_edited() {
undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", base, order);
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", base, order);
- undo_redo->add_do_method(this, "update_autoload");
- undo_redo->add_undo_method(this, "update_autoload");
+ undo_redo->add_do_method(this, "call_deferred", "update_autoload");
+ undo_redo->add_undo_method(this, "call_deferred", "update_autoload");
undo_redo->add_do_method(this, "emit_signal", autoload_changed);
undo_redo->add_undo_method(this, "emit_signal", autoload_changed);
@@ -296,6 +298,18 @@ void EditorAutoloadSettings::update_autoload() {
updating_autoload = true;
+ Map<String, AutoLoadInfo> to_remove;
+ Map<String, AutoLoadInfo> to_remove_singleton;
+ List<AutoLoadInfo> to_add;
+ List<String> to_add_singleton; // Only for when the node is still the same
+
+ for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
+ to_remove.insert(E->get().name, E->get());
+ if (E->get().is_singleton) {
+ to_remove_singleton.insert(E->get().name, E->get());
+ }
+ }
+
autoload_cache.clear();
tree->clear();
@@ -317,19 +331,44 @@ void EditorAutoloadSettings::update_autoload() {
if (name.empty())
continue;
+ AutoLoadInfo old_info;
+ if (to_remove.has(name)) {
+ old_info = to_remove[name];
+ }
+
AutoLoadInfo info;
- info.name = pi.name;
- info.order = ProjectSettings::get_singleton()->get_order(pi.name);
+ info.is_singleton = path.begins_with("*");
- autoload_cache.push_back(info);
+ if (info.is_singleton) {
+ path = path.substr(1, path.length());
+ }
- bool global = false;
+ info.name = name;
+ info.path = path;
+ info.order = ProjectSettings::get_singleton()->get_order(pi.name);
- if (path.begins_with("*")) {
- global = true;
- path = path.substr(1, path.length());
+ if (old_info.name == info.name) {
+ if (old_info.path == info.path) {
+ // Still the same resource, check singleton status
+ to_remove.erase(name);
+ if (info.is_singleton) {
+ if (old_info.is_singleton) {
+ to_remove_singleton.erase(name);
+ } else {
+ to_add_singleton.push_back(name);
+ }
+ }
+ } else {
+ // Resource changed
+ to_add.push_back(info);
+ }
+ } else {
+ // New autoload
+ to_add.push_back(info);
}
+ autoload_cache.push_back(info);
+
TreeItem *item = tree->create_item(root);
item->set_text(0, name);
item->set_editable(0, true);
@@ -340,7 +379,7 @@ void EditorAutoloadSettings::update_autoload() {
item->set_cell_mode(2, TreeItem::CELL_MODE_CHECK);
item->set_editable(2, true);
item->set_text(2, TTR("Enable"));
- item->set_checked(2, global);
+ item->set_checked(2, info.is_singleton);
item->add_button(3, get_icon("FileList", "EditorIcons"), BUTTON_OPEN);
item->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP);
item->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN);
@@ -348,6 +387,77 @@ void EditorAutoloadSettings::update_autoload() {
item->set_selectable(3, false);
}
+ // Remove autoload constants
+ for (Map<String, AutoLoadInfo>::Element *E = to_remove_singleton.front(); E; E = E->next()) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->remove_named_global_constant(E->get().name);
+ }
+ }
+
+ // Remove obsolete nodes from the tree
+ for (Map<String, AutoLoadInfo>::Element *E = to_remove.front(); E; E = E->next()) {
+ AutoLoadInfo &info = E->get();
+ Node *al = get_node("/root/" + info.name);
+ ERR_CONTINUE(!al);
+ get_tree()->get_root()->remove_child(al);
+ memdelete(al);
+ }
+
+ // Register new singletons already in the tree
+ for (List<String>::Element *E = to_add_singleton.front(); E; E = E->next()) {
+ Node *al = get_node("/root/" + E->get());
+ ERR_CONTINUE(!al);
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->add_named_global_constant(E->get(), al);
+ }
+ }
+
+ // Add new nodes to the tree
+ List<Node *> nodes_to_add;
+ for (List<AutoLoadInfo>::Element *E = to_add.front(); E; E = E->next()) {
+ AutoLoadInfo &info = E->get();
+
+ RES res = ResourceLoader::load(info.path);
+ ERR_EXPLAIN("Can't autoload: " + info.path);
+ ERR_CONTINUE(res.is_null());
+ Node *n = NULL;
+ if (res->is_class("PackedScene")) {
+ Ref<PackedScene> ps = res;
+ n = ps->instance();
+ } else if (res->is_class("Script")) {
+ Ref<Script> s = res;
+ StringName ibt = s->get_instance_base_type();
+ bool valid_type = ClassDB::is_parent_class(ibt, "Node");
+ ERR_EXPLAIN("Script does not inherit a Node: " + info.path);
+ ERR_CONTINUE(!valid_type);
+
+ Object *obj = ClassDB::instance(ibt);
+
+ ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
+ ERR_CONTINUE(obj == NULL);
+
+ n = Object::cast_to<Node>(obj);
+ n->set_script(s.get_ref_ptr());
+ }
+
+ ERR_EXPLAIN("Path in autoload not a node or script: " + info.path);
+ ERR_CONTINUE(!n);
+ n->set_name(info.name);
+
+ //defer so references are all valid on _ready()
+ nodes_to_add.push_back(n);
+
+ if (info.is_singleton) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->add_named_global_constant(info.name, n);
+ }
+ }
+ }
+
+ for (List<Node *>::Element *E = nodes_to_add.front(); E; E = E->next()) {
+ get_tree()->get_root()->add_child(E->get());
+ }
+
updating_autoload = false;
}
@@ -592,6 +702,36 @@ void EditorAutoloadSettings::_bind_methods() {
EditorAutoloadSettings::EditorAutoloadSettings() {
+ // Make first cache
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+
+ const PropertyInfo &pi = E->get();
+
+ if (!pi.name.begins_with("autoload/"))
+ continue;
+
+ String name = pi.name.get_slice("/", 1);
+ String path = ProjectSettings::get_singleton()->get(pi.name);
+
+ if (name.empty())
+ continue;
+
+ AutoLoadInfo info;
+ info.is_singleton = path.begins_with("*");
+
+ if (info.is_singleton) {
+ path = path.substr(1, path.length());
+ }
+
+ info.name = name;
+ info.path = path;
+ info.order = ProjectSettings::get_singleton()->get_order(pi.name);
+
+ autoload_cache.push_back(info);
+ }
+
autoload_changed = "autoload_changed";
updating_autoload = false;
diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h
index 6f622de6d5..1797c10e61 100644
--- a/editor/editor_autoload_settings.h
+++ b/editor/editor_autoload_settings.h
@@ -50,6 +50,8 @@ class EditorAutoloadSettings : public VBoxContainer {
struct AutoLoadInfo {
String name;
+ String path;
+ bool is_singleton;
int order;
bool operator==(const AutoLoadInfo &p_info) {
diff --git a/main/main.cpp b/main/main.cpp
index 3542133719..a68f9999ff 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1441,6 +1441,114 @@ bool Main::start() {
}
#endif
+ if (!project_manager) { // game or editor
+ if (game_path != "" || script != "") {
+ //autoload
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+
+ //first pass, add the constants so they exist before any script is loaded
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+
+ String s = E->get().name;
+ if (!s.begins_with("autoload/"))
+ continue;
+ String name = s.get_slicec('/', 1);
+ String path = ProjectSettings::get_singleton()->get(s);
+ bool global_var = false;
+ if (path.begins_with("*")) {
+ global_var = true;
+ }
+
+ if (global_var) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+#ifdef TOOLS_ENABLED
+ if (editor) {
+ ScriptServer::get_language(i)->add_named_global_constant(name, Variant());
+ } else {
+ ScriptServer::get_language(i)->add_global_constant(name, Variant());
+ }
+#else
+ ScriptServer::get_language(i)->add_global_constant(name, Variant());
+#endif
+ }
+ }
+ }
+
+ //second pass, load into global constants
+ List<Node *> to_add;
+#ifdef TOOLS_ENABLED
+ ResourceLoader::set_timestamp_on_load(editor); // Avoid problems when editing
+#endif
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+
+ String s = E->get().name;
+ if (!s.begins_with("autoload/"))
+ continue;
+ String name = s.get_slicec('/', 1);
+ String path = ProjectSettings::get_singleton()->get(s);
+ bool global_var = false;
+ if (path.begins_with("*")) {
+ global_var = true;
+ path = path.substr(1, path.length() - 1);
+ }
+
+ RES res = ResourceLoader::load(path);
+ ERR_EXPLAIN("Can't autoload: " + path);
+ ERR_CONTINUE(res.is_null());
+ Node *n = NULL;
+ if (res->is_class("PackedScene")) {
+ Ref<PackedScene> ps = res;
+ n = ps->instance();
+ } else if (res->is_class("Script")) {
+ Ref<Script> s = res;
+ StringName ibt = s->get_instance_base_type();
+ bool valid_type = ClassDB::is_parent_class(ibt, "Node");
+ ERR_EXPLAIN("Script does not inherit a Node: " + path);
+ ERR_CONTINUE(!valid_type);
+
+ Object *obj = ClassDB::instance(ibt);
+
+ ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
+ ERR_CONTINUE(obj == NULL);
+
+ n = Object::cast_to<Node>(obj);
+ n->set_script(s.get_ref_ptr());
+ }
+
+ ERR_EXPLAIN("Path in autoload not a node or script: " + path);
+ ERR_CONTINUE(!n);
+ n->set_name(name);
+
+ //defer so references are all valid on _ready()
+ to_add.push_back(n);
+
+ if (global_var) {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+#ifdef TOOLS_ENABLED
+ if (editor) {
+ ScriptServer::get_language(i)->add_named_global_constant(name, n);
+ } else {
+ ScriptServer::get_language(i)->add_global_constant(name, n);
+ }
+#else
+ ScriptServer::get_language(i)->add_global_constant(name, n);
+#endif
+ }
+ }
+ }
+
+#ifdef TOOLS_ENABLED
+ ResourceLoader::set_timestamp_on_load(false);
+#endif
+
+ for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) {
+
+ sml->get_root()->add_child(E->get());
+ }
+ }
+ }
+
#ifdef TOOLS_ENABLED
EditorNode *editor_node = NULL;
@@ -1460,9 +1568,6 @@ bool Main::start() {
}
#endif
- {
- }
-
if (!editor && !project_manager) {
//standard helpers that can be changed from main config
@@ -1575,89 +1680,6 @@ bool Main::start() {
}
if (!project_manager && !editor) { // game
- if (game_path != "" || script != "") {
- //autoload
- List<PropertyInfo> props;
- ProjectSettings::get_singleton()->get_property_list(&props);
-
- //first pass, add the constants so they exist before any script is loaded
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- String s = E->get().name;
- if (!s.begins_with("autoload/"))
- continue;
- String name = s.get_slicec('/', 1);
- String path = ProjectSettings::get_singleton()->get(s);
- bool global_var = false;
- if (path.begins_with("*")) {
- global_var = true;
- }
-
- if (global_var) {
- for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- ScriptServer::get_language(i)->add_global_constant(name, Variant());
- }
- }
- }
-
- //second pass, load into global constants
- List<Node *> to_add;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- String s = E->get().name;
- if (!s.begins_with("autoload/"))
- continue;
- String name = s.get_slicec('/', 1);
- String path = ProjectSettings::get_singleton()->get(s);
- bool global_var = false;
- if (path.begins_with("*")) {
- global_var = true;
- path = path.substr(1, path.length() - 1);
- }
-
- RES res = ResourceLoader::load(path);
- ERR_EXPLAIN("Can't autoload: " + path);
- ERR_CONTINUE(res.is_null());
- Node *n = NULL;
- if (res->is_class("PackedScene")) {
- Ref<PackedScene> ps = res;
- n = ps->instance();
- } else if (res->is_class("Script")) {
- Ref<Script> s = res;
- StringName ibt = s->get_instance_base_type();
- bool valid_type = ClassDB::is_parent_class(ibt, "Node");
- ERR_EXPLAIN("Script does not inherit a Node: " + path);
- ERR_CONTINUE(!valid_type);
-
- Object *obj = ClassDB::instance(ibt);
-
- ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
- ERR_CONTINUE(obj == NULL);
-
- n = Object::cast_to<Node>(obj);
- n->set_script(s.get_ref_ptr());
- }
-
- ERR_EXPLAIN("Path in autoload not a node or script: " + path);
- ERR_CONTINUE(!n);
- n->set_name(name);
-
- //defer so references are all valid on _ready()
- to_add.push_back(n);
-
- if (global_var) {
- for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- ScriptServer::get_language(i)->add_global_constant(name, n);
- }
- }
- }
-
- for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) {
-
- sml->get_root()->add_child(E->get());
- }
- }
-
if (game_path != "") {
Node *scene = NULL;
Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 4e3ee4d22c..14bdce50ec 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1333,6 +1333,15 @@ void GDScriptLanguage::add_global_constant(const StringName &p_variable, const V
_add_global(p_variable, p_value);
}
+void GDScriptLanguage::add_named_global_constant(const StringName &p_name, const Variant &p_value) {
+ named_globals[p_name] = p_value;
+}
+
+void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) {
+ ERR_FAIL_COND(!named_globals.has(p_name));
+ named_globals.erase(p_name);
+}
+
void GDScriptLanguage::init() {
//populate global constants
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 9566e3b32e..6885fbb7fe 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -262,6 +262,7 @@ class GDScriptLanguage : public ScriptLanguage {
Variant *_global_array;
Vector<Variant> global_array;
Map<StringName, int> globals;
+ Map<StringName, Variant> named_globals;
struct CallLevel {
@@ -369,7 +370,8 @@ public:
_FORCE_INLINE_ int get_global_array_size() const { return global_array.size(); }
_FORCE_INLINE_ Variant *get_global_array() { return _global_array; }
- _FORCE_INLINE_ const Map<StringName, int> &get_global_map() { return globals; }
+ _FORCE_INLINE_ const Map<StringName, int> &get_global_map() const { return globals; }
+ _FORCE_INLINE_ const Map<StringName, Variant> &get_named_globals_map() const { return named_globals; }
_FORCE_INLINE_ static GDScriptLanguage *get_singleton() { return singleton; }
@@ -403,6 +405,8 @@ public:
virtual String _get_indentation() const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
+ virtual void add_named_global_constant(const StringName &p_name, const Variant &p_value);
+ virtual void remove_named_global_constant(const StringName &p_name);
/* DEBUGGER FUNCTIONS */
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 048948dada..9947512444 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -278,6 +278,18 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
}
+#ifdef TOOLS_ENABLED
+ if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
+
+ int idx = codegen.named_globals.find(identifier);
+ if (idx == -1) {
+ idx = codegen.named_globals.size();
+ codegen.named_globals.push_back(identifier);
+ }
+ return idx | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
+ }
+#endif
+
//not found, error
_set_error("Identifier not found: " + String(identifier), p_expression);
@@ -1511,6 +1523,18 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_global_names_count = 0;
}
+#ifdef TOOLS_ENABLED
+ // Named globals
+ if (codegen.named_globals.size()) {
+ gdfunc->named_globals.resize(codegen.named_globals.size());
+ gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
+ for (int i = 0; i < codegen.named_globals.size(); i++) {
+ gdfunc->named_globals[i] = codegen.named_globals[i];
+ }
+ gdfunc->_named_globals_count = gdfunc->named_globals.size();
+ }
+#endif
+
if (codegen.opcodes.size()) {
gdfunc->code = codegen.opcodes;
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 62aafdbe01..237b0de9e7 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -94,6 +94,9 @@ class GDScriptCompiler {
HashMap<Variant, int, VariantHasher, VariantComparator> constant_map;
Map<StringName, int> name_map;
+#ifdef TOOLS_ENABLED
+ Vector<StringName> named_globals;
+#endif
int get_name_map_pos(const StringName &p_identifier) {
int ret;
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index d32ce25d3c..62394c8c43 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -108,6 +108,21 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
#endif
return &GDScriptLanguage::get_singleton()->get_global_array()[address];
} break;
+#ifdef TOOLS_ENABLED
+ case ADDR_TYPE_NAMED_GLOBAL: {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(address, _named_globals_count, NULL);
+#endif
+ StringName id = _named_globals_ptr[address];
+
+ if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(id)) {
+ return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
+ } else {
+ r_error = "Autoload singleton '" + String(id) + "' has been removed.";
+ return NULL;
+ }
+ } break;
+#endif
case ADDR_TYPE_NIL: {
return &nil;
} break;
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index dff4bdfaf2..ea009dcd96 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -92,7 +92,8 @@ public:
ADDR_TYPE_STACK = 5,
ADDR_TYPE_STACK_VARIABLE = 6,
ADDR_TYPE_GLOBAL = 7,
- ADDR_TYPE_NIL = 8
+ ADDR_TYPE_NAMED_GLOBAL = 8,
+ ADDR_TYPE_NIL = 9
};
enum RPCMode {
@@ -121,6 +122,10 @@ private:
int _constant_count;
const StringName *_global_names_ptr;
int _global_names_count;
+#ifdef TOOLS_ENABLED
+ const StringName *_named_globals_ptr;
+ int _named_globals_count;
+#endif
const int *_default_arg_ptr;
int _default_arg_count;
const int *_code_ptr;
@@ -137,6 +142,9 @@ private:
StringName name;
Vector<Variant> constants;
Vector<StringName> global_names;
+#ifdef TOOLS_ENABLED
+ Vector<StringName> named_globals;
+#endif
Vector<int> default_arguments;
Vector<int> code;