Mono: Fix hot reload build errors and cleanup
This commit is contained in:
parent
077e489773
commit
bc8b61bb06
6 changed files with 43 additions and 15 deletions
|
@ -88,6 +88,9 @@ vars.Update(env_mono)
|
||||||
if env_mono['mono_glue']:
|
if env_mono['mono_glue']:
|
||||||
env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
|
env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
|
||||||
|
|
||||||
|
if env_mono['tools'] or env_mono['target'] != 'release':
|
||||||
|
env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD'])
|
||||||
|
|
||||||
# Configure TLS checks
|
# Configure TLS checks
|
||||||
|
|
||||||
import tls_configure
|
import tls_configure
|
||||||
|
|
|
@ -607,7 +607,7 @@ struct CSharpScriptDepSort {
|
||||||
|
|
||||||
void CSharpLanguage::reload_all_scripts() {
|
void CSharpLanguage::reload_all_scripts() {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
if (is_assembly_reloading_needed()) {
|
if (is_assembly_reloading_needed()) {
|
||||||
reload_assemblies(false);
|
reload_assemblies(false);
|
||||||
}
|
}
|
||||||
|
@ -618,15 +618,20 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
|
||||||
|
|
||||||
(void)p_script; // UNUSED
|
(void)p_script; // UNUSED
|
||||||
|
|
||||||
|
CRASH_COND(!Engine::get_singleton()->is_editor_hint());
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
MonoReloadNode::get_singleton()->restart_reload_timer();
|
MonoReloadNode::get_singleton()->restart_reload_timer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
if (is_assembly_reloading_needed()) {
|
if (is_assembly_reloading_needed()) {
|
||||||
reload_assemblies(p_soft_reload);
|
reload_assemblies(p_soft_reload);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
bool CSharpLanguage::is_assembly_reloading_needed() {
|
bool CSharpLanguage::is_assembly_reloading_needed() {
|
||||||
|
|
||||||
if (!gdmono->is_runtime_initialized())
|
if (!gdmono->is_runtime_initialized())
|
||||||
|
@ -658,11 +663,13 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
|
||||||
return false; // No assembly to load
|
return false; // No assembly to load
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE))
|
if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE))
|
||||||
return false; // The core API assembly to load is invalidated
|
return false; // The core API assembly to load is invalidated
|
||||||
|
|
||||||
if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR))
|
if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR))
|
||||||
return false; // The editor API assembly to load is invalidated
|
return false; // The editor API assembly to load is invalidated
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -760,9 +767,11 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
||||||
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
|
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
|
||||||
obj->set_script_instance(placeholder);
|
obj->set_script_instance(placeholder);
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
// Even though build didn't fail, this tells the placeholder to keep properties and
|
// Even though build didn't fail, this tells the placeholder to keep properties and
|
||||||
// it allows using property_set_fallback for restoring the state without a valid script.
|
// it allows using property_set_fallback for restoring the state without a valid script.
|
||||||
scr->placeholder_fallback_enabled = true;
|
scr->placeholder_fallback_enabled = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restore Variant properties state, it will be kept by the placeholder until the next script reloading
|
// Restore Variant properties state, it will be kept by the placeholder until the next script reloading
|
||||||
for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) {
|
for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) {
|
||||||
|
@ -778,13 +787,14 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
||||||
for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) {
|
for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Ref<CSharpScript> scr = E->get();
|
Ref<CSharpScript> scr = E->get();
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
scr->exports_invalidated = true;
|
scr->exports_invalidated = true;
|
||||||
|
#endif
|
||||||
scr->signals_invalidated = true;
|
scr->signals_invalidated = true;
|
||||||
scr->reload(p_soft_reload);
|
scr->reload(p_soft_reload);
|
||||||
scr->update_exports();
|
scr->update_exports();
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
for (Set<ObjectID>::Element *F = scr->pending_reload_instances.front(); F; F = F->next()) {
|
for (Set<ObjectID>::Element *F = scr->pending_reload_instances.front(); F; F = F->next()) {
|
||||||
ObjectID obj_id = F->get();
|
ObjectID obj_id = F->get();
|
||||||
Object *obj = ObjectDB::get_instance(obj_id);
|
Object *obj = ObjectDB::get_instance(obj_id);
|
||||||
|
@ -843,17 +853,18 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
||||||
|
|
||||||
scr->pending_reload_state.erase(obj_id);
|
scr->pending_reload_state.erase(obj_id);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
scr->pending_reload_instances.clear();
|
scr->pending_reload_instances.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
// FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative.
|
// FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative.
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
EditorNode::get_singleton()->get_inspector()->update_tree();
|
EditorNode::get_singleton()->get_inspector()->update_tree();
|
||||||
NodeDock::singleton->update_lists();
|
NodeDock::singleton->update_lists();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2810,9 +2821,11 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
|
||||||
file->close();
|
file->close();
|
||||||
memdelete(file);
|
memdelete(file);
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
if (ScriptServer::is_reload_scripts_on_save_enabled()) {
|
if (ScriptServer::is_reload_scripts_on_save_enabled()) {
|
||||||
CSharpLanguage::get_singleton()->reload_tool_script(p_resource, false);
|
CSharpLanguage::get_singleton()->reload_tool_script(p_resource, false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,10 +82,7 @@ class CSharpScript : public Script {
|
||||||
|
|
||||||
Set<Object *> instances;
|
Set<Object *> instances;
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
Set<ObjectID> pending_reload_instances;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct StateBackup {
|
struct StateBackup {
|
||||||
// TODO
|
// TODO
|
||||||
// Replace with buffer containing the serialized state of managed scripts.
|
// Replace with buffer containing the serialized state of managed scripts.
|
||||||
|
@ -93,8 +90,8 @@ class CSharpScript : public Script {
|
||||||
List<Pair<StringName, Variant> > properties;
|
List<Pair<StringName, Variant> > properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
Set<ObjectID> pending_reload_instances;
|
||||||
Map<ObjectID, CSharpScript::StateBackup> pending_reload_state;
|
Map<ObjectID, StateBackup> pending_reload_state;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
@ -313,7 +310,7 @@ public:
|
||||||
bool debug_break(const String &p_error, bool p_allow_continue = true);
|
bool debug_break(const String &p_error, bool p_allow_continue = true);
|
||||||
bool debug_break_parse(const String &p_file, int p_line, const String &p_error);
|
bool debug_break_parse(const String &p_file, int p_line, const String &p_error);
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
bool is_assembly_reloading_needed();
|
bool is_assembly_reloading_needed();
|
||||||
void reload_assemblies(bool p_soft_reload);
|
void reload_assemblies(bool p_soft_reload);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -731,7 +731,9 @@ Error GDMono::_unload_scripts_domain() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
core_api_assembly_out_of_sync = false;
|
core_api_assembly_out_of_sync = false;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
editor_api_assembly_out_of_sync = false;
|
editor_api_assembly_out_of_sync = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
MonoDomain *domain = scripts_domain;
|
MonoDomain *domain = scripts_domain;
|
||||||
scripts_domain = NULL;
|
scripts_domain = NULL;
|
||||||
|
@ -764,7 +766,7 @@ Error GDMono::_load_tools_domain() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
Error GDMono::reload_scripts_domain() {
|
Error GDMono::reload_scripts_domain() {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
|
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
|
||||||
|
@ -785,8 +787,12 @@ Error GDMono::reload_scripts_domain() {
|
||||||
|
|
||||||
#ifdef MONO_GLUE_ENABLED
|
#ifdef MONO_GLUE_ENABLED
|
||||||
if (!_load_api_assemblies()) {
|
if (!_load_api_assemblies()) {
|
||||||
if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
|
if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated))
|
||||||
(editor_api_assembly && editor_api_assembly_out_of_sync)) {
|
#ifdef TOOLS_ENABLED
|
||||||
|
|| (editor_api_assembly && editor_api_assembly_out_of_sync)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
// The assembly was successfully loaded, but the full api could not be cached.
|
// The assembly was successfully loaded, but the full api could not be cached.
|
||||||
// This is most likely an outdated assembly loaded because of an invalid version in the
|
// This is most likely an outdated assembly loaded because of an invalid version in the
|
||||||
// metadata, so we invalidate the version in the metadata and unload the script domain.
|
// metadata, so we invalidate the version in the metadata and unload the script domain.
|
||||||
|
@ -810,6 +816,10 @@ Error GDMono::reload_scripts_domain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_CANT_RESOLVE;
|
return ERR_CANT_RESOLVE;
|
||||||
|
#else
|
||||||
|
ERR_PRINT("The loaded API assembly is invalid");
|
||||||
|
CRASH_NOW();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
return ERR_CANT_OPEN;
|
return ERR_CANT_OPEN;
|
||||||
}
|
}
|
||||||
|
@ -924,7 +934,9 @@ GDMono::GDMono() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
core_api_assembly_out_of_sync = false;
|
core_api_assembly_out_of_sync = false;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
editor_api_assembly_out_of_sync = false;
|
editor_api_assembly_out_of_sync = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
corlib_assembly = NULL;
|
corlib_assembly = NULL;
|
||||||
core_api_assembly = NULL;
|
core_api_assembly = NULL;
|
||||||
|
|
|
@ -95,7 +95,9 @@ class GDMono {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool core_api_assembly_out_of_sync;
|
bool core_api_assembly_out_of_sync;
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
bool editor_api_assembly_out_of_sync;
|
bool editor_api_assembly_out_of_sync;
|
||||||
|
#endif
|
||||||
|
|
||||||
GDMonoAssembly *corlib_assembly;
|
GDMonoAssembly *corlib_assembly;
|
||||||
GDMonoAssembly *core_api_assembly;
|
GDMonoAssembly *core_api_assembly;
|
||||||
|
@ -193,7 +195,7 @@ public:
|
||||||
|
|
||||||
GDMonoClass *get_class(MonoClass *p_raw_class);
|
GDMonoClass *get_class(MonoClass *p_raw_class);
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef GD_MONO_HOT_RELOAD
|
||||||
Error reload_scripts_domain();
|
Error reload_scripts_domain();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "core/ustring.h"
|
#include "core/ustring.h"
|
||||||
|
|
||||||
#ifndef OSX_UTILS_H
|
#ifndef OSX_UTILS_H
|
||||||
|
#define OSX_UTILS_H
|
||||||
|
|
||||||
#ifdef OSX_ENABLED
|
#ifdef OSX_ENABLED
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue