Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for interactive loader with subscenes #3

Open
wants to merge 1 commit into
base: GodotTestMaster
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/io/resource_format_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ Error ResourceInteractiveLoaderBinary::poll() {
error = OK;
}

return OK;
return error;
}
int ResourceInteractiveLoaderBinary::get_stage() const {

Expand Down
16 changes: 15 additions & 1 deletion core/io/resource_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,22 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return OK;
}

RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error) {
Ref<ResourceInteractiveLoader> ResourceFormatImporter::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);

if (err != OK) {

if (r_error)
*r_error = err;

return RES();
}

return ResourceLoader::load_interactive(pat.path, pat.type, true, r_error);
}

RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);

Expand Down
1 change: 1 addition & 0 deletions core/io/resource_importer.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {

public:
static ResourceFormatImporter *get_singleton() { return singleton; }
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
Expand Down
6 changes: 6 additions & 0 deletions core/io/resource_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ class ResourceInteractiveLoaderDefault : public ResourceInteractiveLoader {
ResourceInteractiveLoaderDefault() {}
};

void ResourceInteractiveLoader::set_preloaded_resources(const Map<String, RES> &p_preloaded_resources) {
for(Map<String, RES>::Element *E=p_preloaded_resources.front();E;E=E->next()) {
preloaded_resources[E->key()] = E->get();
}
}

Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {

//either this
Expand Down
3 changes: 3 additions & 0 deletions core/io/resource_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class ResourceInteractiveLoader : public Reference {

protected:
static void _bind_methods();
Map<String, RES> preloaded_resources;

public:
virtual void set_local_path(const String &p_local_path) = 0;
Expand All @@ -52,6 +53,8 @@ class ResourceInteractiveLoader : public Reference {
virtual int get_stage_count() const = 0;
virtual void set_translation_remapped(bool p_remapped) = 0;
virtual Error wait();
void set_preloaded_resources(const Map<String, RES> &p_preloaded_resources);
Map<String, RES> get_preloaded_resources(){return preloaded_resources;};

ResourceInteractiveLoader() {}
~ResourceInteractiveLoader();
Expand Down
134 changes: 133 additions & 1 deletion modules/gdscript/gdscript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,10 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
}

Error GDScript::reload(bool p_keep_state) {
return _reload(p_keep_state, Map<String, RES>());
}

Error GDScript::_reload(bool p_keep_state, const Map<String, RES> &preloaded_resources) {

#ifndef NO_THREADS
GDScriptLanguage::singleton->lock->lock();
Expand Down Expand Up @@ -567,6 +571,9 @@ Error GDScript::reload(bool p_keep_state) {

valid = false;
GDScriptParser parser;

// WARN_PRINT("PARSE");
parser.set_preloaded_resources(preloaded_resources);
Error err = parser.parse(source, basedir, false, path);
if (err) {
if (ScriptDebugger::get_singleton()) {
Expand All @@ -578,6 +585,8 @@ Error GDScript::reload(bool p_keep_state) {

bool can_run = ScriptServer::is_scripting_enabled() || parser.is_tool_script();

// WARN_PRINT("COMPILE");

GDScriptCompiler compiler;
err = compiler.compile(&parser, this, p_keep_state);

Expand Down Expand Up @@ -721,7 +730,7 @@ Vector<uint8_t> GDScript::get_as_byte_code() const {
return tokenizer.parse_code_string(source);
};

Error GDScript::load_byte_code(const String &p_path) {
Error GDScript::load_byte_code(const String &p_path, const Map<String, RES> &preloaded_resources) {

Vector<uint8_t> bytecode;

Expand Down Expand Up @@ -772,13 +781,16 @@ Error GDScript::load_byte_code(const String &p_path) {

valid = false;
GDScriptParser parser;
WARN_PRINT("PARSE BYTE CODE");
parser.set_preloaded_resources(preloaded_resources);
Error err = parser.parse_bytecode(bytecode, basedir, get_path());
if (err) {
_err_print_error("GDScript::load_byte_code", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_error_line(), ("Parse Error: " + parser.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
ERR_FAIL_V(ERR_PARSE_ERROR);
}

GDScriptCompiler compiler;
WARN_PRINT("COMPILE");
err = compiler.compile(&parser, this);

if (err) {
Expand Down Expand Up @@ -2162,6 +2174,126 @@ GDScriptLanguage::~GDScriptLanguage() {
}

/*************** RESOURCE ***************/
void ResourceInteractiveFormatLoaderGDScript::set_local_path(const String &p_local_path) {

}
Ref<Resource> ResourceInteractiveFormatLoaderGDScript::get_resource() {
return resource;
}

Error ResourceInteractiveFormatLoaderGDScript::_poll_dependency() {
error = dependency_loader->poll();
if (error != ERR_FILE_EOF) {
return error;
}

RES res = dependency_loader->get_resource();
set_preloaded_resources(dependency_loader->get_preloaded_resources());
dependency_loader.unref();

preloaded_resources[dependencies[stage]] = res;

stage++;
return OK;
}

Error ResourceInteractiveFormatLoaderGDScript::poll() {
if (!dependency_loader.is_null()) {
return _poll_dependency();
}

while (stage < dependencies.size()) {
String d = dependencies[stage];
// WARN_PRINT(String("STAGE: " + itos(stage) + " : " + d).ascii().get_data());

if (preloaded_resources.has(d)) {
// WARN_PRINT("Resource already in loaded - skipping");
stage++;
continue;
} else if (d.ends_with(".gd") || d.ends_with(".tscn") || d.ends_with(".scn")) {
dependency_loader = ResourceLoader::load_interactive(d);
if (dependency_loader.is_null()) {
return ERR_FILE_CORRUPT;
}
dependency_loader->set_preloaded_resources(preloaded_resources);
return _poll_dependency();
} else {
preloaded_resources[d] = ResourceLoader::load(d);
stage++;
return OK;
}
}

// Load script itself

GDScript *script = memnew(GDScript);
Ref<GDScript> scriptres(script);

if (binary) {
script->set_script_path(original_path); // script needs this.
script->set_path(original_path);

error = script->load_byte_code(script_path, preloaded_resources);
} else {
error = script->load_source_code(script_path);

script->set_script_path(original_path); // script needs this.
script->set_path(original_path);

script->_reload(false, preloaded_resources);
}

resource = scriptres;

if (error == OK) {
return ERR_FILE_EOF;
}
return error;
}
int ResourceInteractiveFormatLoaderGDScript::get_stage() const {
return stage;
}
int ResourceInteractiveFormatLoaderGDScript::get_stage_count() const {
return 1;
}

void ResourceInteractiveFormatLoaderGDScript::set_translation_remapped(bool p_remapped) {}

ResourceInteractiveFormatLoaderGDScript::ResourceInteractiveFormatLoaderGDScript(){}
ResourceInteractiveFormatLoaderGDScript::~ResourceInteractiveFormatLoaderGDScript(){}


Ref<ResourceInteractiveLoader> ResourceFormatLoaderGDScript::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
if (r_error)
*r_error = ERR_CANT_OPEN;

FileAccessRef file = FileAccess::open(p_path, FileAccess::READ);
if (!file)
*r_error = ERR_CANT_OPEN;

Ref<ResourceInteractiveFormatLoaderGDScript> ria = memnew(ResourceInteractiveFormatLoaderGDScript);
ria->stage = 0;
ria->script_path = p_path;
ria->original_path = p_original_path;
ria->binary = (p_path.ends_with(".gde") || p_path.ends_with(".gdc"));

// WARN_PRINT("CHECK_DEPENDENCIES");
String source = file->get_as_utf8_string();
if (!source.empty()) {
GDScriptParser parser;
// WARN_PRINT("CHECK_SOURCE_OK");
if (OK == parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true)) {
// WARN_PRINT("OK_PARSE_DEPENDENCIES");
for (const List<String>::Element *E = parser.get_dependencies().front(); E; E = E->next()) {
// WARN_PRINT(String("DEPENDENCY!: " + E->get()).ascii().get_data());
String dependency_path = E->get();
ria->dependencies.push_back(dependency_path);
}
}
}

return ria;
}

RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error) {

Expand Down
33 changes: 32 additions & 1 deletion modules/gdscript/gdscript.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ class GDScript : public Script {
virtual void update_exports();

virtual Error reload(bool p_keep_state = false);
Error _reload(bool p_keep_state, const Map<String, RES> &preloaded_resources);

void set_script_path(const String &p_path) { path = p_path; } //because subclasses need a path too...
Error load_source_code(const String &p_path);
Error load_byte_code(const String &p_path);
Error load_byte_code(const String &p_path, const Map<String, RES> &preloaded_resources = Map<String, RES>());

Vector<uint8_t> get_as_byte_code() const;

Expand Down Expand Up @@ -508,8 +509,38 @@ class GDScriptLanguage : public ScriptLanguage {
~GDScriptLanguage();
};

class ResourceInteractiveFormatLoaderGDScript : public ResourceInteractiveLoader {
friend class ResourceFormatLoaderGDScript;

int stage;

String script_path;
String original_path;
bool binary;

List<String> dependencies;
Ref<ResourceInteractiveLoader> dependency_loader;

Error error;
RES resource;

Error _poll_dependency();

public:
virtual void set_local_path(const String &p_local_path);
virtual Ref<Resource> get_resource();
virtual Error poll();
virtual int get_stage() const;
virtual int get_stage_count() const;
virtual void set_translation_remapped(bool p_remapped);

ResourceInteractiveFormatLoaderGDScript();
~ResourceInteractiveFormatLoaderGDScript();
};

class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
Expand Down
13 changes: 12 additions & 1 deletion modules/gdscript/gdscript_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,9 +487,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (!validating) {

//this can be too slow for just validating code
if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) {
if (preloaded_resources.has(path)) {
// WARN_PRINT(String("GETTING PRELOADED RESOURCE: " + path).ascii().get_data());
res = preloaded_resources[path];
} else if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) {
// WARN_PRINT(String("LOADING CACHED RESOURCE: " + path).ascii().get_data());
res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
} else if (!for_completion || FileAccess::exists(path)) {
// WARN_PRINT(String("LOADING RESOURCE: " + path).ascii().get_data());
res = ResourceLoader::load(path);
}
} else {
Expand Down Expand Up @@ -8506,6 +8511,12 @@ Error GDScriptParser::parse(const String &p_code, const String &p_base_path, boo
return ret;
}

void GDScriptParser::set_preloaded_resources(const Map<String, RES> &p_preloaded_resources) {
for(Map<String, RES>::Element *E=p_preloaded_resources.front();E;E=E->next()) {
preloaded_resources[E->key()] = E->get();
}
}

bool GDScriptParser::is_tool_script() const {

return (head && head->type == Node::TYPE_CLASS && static_cast<const ClassNode *>(head)->tool);
Expand Down
2 changes: 2 additions & 0 deletions modules/gdscript/gdscript_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ class GDScriptParser {
bool check_types;
bool dependencies_only;
List<String> dependencies;
Map<String, RES> preloaded_resources;
#ifdef DEBUG_ENABLED
Set<int> *safe_lines;
#endif // DEBUG_ENABLED
Expand Down Expand Up @@ -665,6 +666,7 @@ class GDScriptParser {
int get_completion_identifier_is_function();

const List<String> &get_dependencies() const { return dependencies; }
void set_preloaded_resources(const Map<String, RES> &p_preloaded_resources);

void clear();
GDScriptParser();
Expand Down
Loading