Skip to content

Commit eac4c95

Browse files
committed
Preload scripts for registering system and component names
1 parent e0c8e08 commit eac4c95

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed

ecs.cpp

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11

22
#include "ecs.h"
3+
#include <core/config/project_settings.h>
4+
#include <core/io/dir_access.h>
5+
#include <modules/gdscript/gdscript_parser.h>
36

47
#include "components/dynamic_component.h"
58
#include "core/object/message_queue.h"
@@ -159,6 +162,43 @@ ECS::ECS() :
159162
}
160163
}
161164

165+
void get_script_files(const String &p_path, Vector<String> &scripts) {
166+
for (const auto &directory : DirAccess::get_directories_at(p_path)) {
167+
get_script_files(p_path.path_join(directory), scripts);
168+
}
169+
for (const auto &file : DirAccess::get_files_at(p_path)) {
170+
auto file_path = p_path.path_join(file);
171+
if (ResourceLoader::get_resource_type(file_path) == "GDScript") {
172+
scripts.push_back(file_path);
173+
}
174+
}
175+
}
176+
177+
void ECS::preload_scripts() {
178+
if (Engine::get_singleton()->is_project_manager_hint()) {
179+
return;
180+
}
181+
182+
Vector<String> scripts;
183+
184+
get_script_files("res://", scripts);
185+
186+
for (const auto &script : scripts) {
187+
auto code = FileAccess::get_file_as_string(script);
188+
GDScriptParser parser;
189+
if (parser.parse(code, script, false) == OK) {
190+
auto tree = parser.get_tree();
191+
if (tree->extends.has("System")) {
192+
register_dynamic_system(script.get_file());
193+
}
194+
195+
if (tree->extends.has("Component")) {
196+
register_or_get_id_for_component_name(script.get_file());
197+
}
198+
}
199+
}
200+
}
201+
162202
ECS::~ECS() {
163203
}
164204

@@ -1041,11 +1081,7 @@ const LocalVector<godex::component_id> &ECS::get_spawnable_components(godex::spa
10411081
return spawners_info[p_spawner].components;
10421082
}
10431083

1044-
uint32_t ECS::register_or_update_script_component(
1045-
const StringName &p_name,
1046-
const LocalVector<ScriptProperty> &p_properties,
1047-
StorageType p_storage_type,
1048-
Vector<StringName> p_spawners) {
1084+
uint32_t ECS::register_or_get_id_for_component_name(const StringName &p_name) {
10491085
godex::component_id id = get_component_id(p_name);
10501086
DynamicComponentInfo *info;
10511087

@@ -1058,12 +1094,25 @@ uint32_t ECS::register_or_update_script_component(
10581094
components.push_back(p_name);
10591095
components_info.push_back(ComponentInfo());
10601096
components_info[id].dynamic_component_info = info;
1061-
} else {
1062-
// This is an old component, verify is a script component.
1063-
ERR_FAIL_COND_V_MSG(components_info[id].dynamic_component_info == nullptr, godex::COMPONENT_NONE, "This component " + p_name + " is not a script component and can't be updated. Your component must be an unique name.");
1064-
info = components_info[id].dynamic_component_info;
1097+
1098+
// Add a new scripting constant, for fast and easy `component` access.
1099+
ClassDB::bind_integer_constant(get_class_static(), StringName(), String(p_name).replace(".", "_"), id);
1100+
print_line("ComponentScript: " + p_name + " registered with ID: " + itos(id));
10651101
}
10661102

1103+
return id;
1104+
}
1105+
1106+
uint32_t ECS::register_or_update_script_component(
1107+
const StringName &p_name,
1108+
const LocalVector<ScriptProperty> &p_properties,
1109+
StorageType p_storage_type,
1110+
Vector<StringName> p_spawners) {
1111+
godex::component_id id = register_or_get_id_for_component_name(p_name);
1112+
DynamicComponentInfo *info;
1113+
ERR_FAIL_COND_V_MSG(components_info[id].dynamic_component_info == nullptr, godex::COMPONENT_NONE, "This component " + p_name + " is not a script component and can't be updated. Your component must be an unique name.");
1114+
info = components_info[id].dynamic_component_info;
1115+
10671116
info->property_map.resize(p_properties.size());
10681117
info->properties.resize(p_properties.size());
10691118
info->defaults.resize(p_properties.size());
@@ -1115,10 +1164,6 @@ uint32_t ECS::register_or_update_script_component(
11151164
spawners_info[spawner].components.push_back(info->component_id);
11161165
}
11171166

1118-
// Add a new scripting constant, for fast and easy `component` access.
1119-
ClassDB::bind_integer_constant(get_class_static(), StringName(), String(p_name).replace(".", "_"), id);
1120-
print_line("ComponentScript: " + p_name + " registered with ID: " + itos(id));
1121-
11221167
return id;
11231168
}
11241169

ecs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class ECS : public Object {
224224
template <class C>
225225
static void register_component(StorageBase *(*create_storage)());
226226

227+
static uint32_t register_or_get_id_for_component_name(const StringName &p_name);
227228
static uint32_t register_or_update_script_component(const StringName &p_name, const LocalVector<ScriptProperty> &p_properties, StorageType p_storage_type, Vector<StringName> p_spawners);
228229

229230
static uint32_t get_components_count();
@@ -488,6 +489,8 @@ class ECS : public Object {
488489
/// time, making the pipeline switch immediate.
489490
static void system_set_active_system(godex::system_id p_id, uint8_t *p_mem, bool p_active);
490491

492+
static void preload_scripts();
493+
491494
private:
492495
static void clear_emitters_for_system(godex::system_id p_id);
493496

modules/godot/nodes/script_ecs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "script_ecs.h"
2+
#include <modules/gdscript/gdscript_parser.h>
23

34
#include "../../../ecs.h"
45
#include "../../../systems/dynamic_system.h"

modules/godot/register_types.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ void initialize_godot_module(ModuleInitializationLevel p_level) {
137137

138138
ClassDB::register_class<SharedComponentResource>();
139139

140+
ECS::preload_scripts();
141+
140142
memnew(ScriptEcs());
141143

142144
} else if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {

0 commit comments

Comments
 (0)