C#: Restructure code prior move to .NET Core
The main focus here was to remove the majority of code that relied on Mono's embedding APIs, specially the reflection APIs. The embedding APIs we still use are the bare minimum we need for things to work. A lot of code was moved to C#. We no longer deal with any managed objects (`MonoObject*`, and such) in native code, and all marshaling is done in C#. The reason for restructuring the code and move away from embedding APIs is that once we move to .NET Core, we will be limited by the much more minimal .NET hosting. PERFORMANCE REGRESSIONS ----------------------- Some parts of the code were written with little to no concern about performance. This includes code that calls into script methods and accesses script fields, properties and events. The reason for this is that all of that will be moved to source generators, so any work prior to that would be a waste of time. DISABLED FEATURES ----------------- Some code was removed as it no longer makes sense (or won't make sense in the future). Other parts were commented out with `#if 0`s and TODO warnings because it doesn't make much sense to work on them yet as those parts will change heavily when we switch to .NET Core but also when we start introducing source generators. As such, the following features were disabled temporarily: - Assembly-reloading (will be done with ALCs in .NET Core). - Properties/fields exports and script method listing (will be handled by source generators in the future). - Exception logging in the editor and stack info for errors. - Exporting games. - Building of C# projects. We no longer copy the Godot API assemblies to the project directory, so MSBuild won't be able to find them. The idea is to turn them into NuGet packages in the future, which could also be obtained from local NuGet sources during development.
This commit is contained in:
@@ -41,31 +41,6 @@
|
||||
#include "../utils/mono_reg_utils.h"
|
||||
#endif
|
||||
|
||||
namespace ApiAssemblyInfo {
|
||||
enum Type {
|
||||
API_CORE,
|
||||
API_EDITOR
|
||||
};
|
||||
|
||||
struct Version {
|
||||
uint64_t godot_api_hash = 0;
|
||||
|
||||
bool operator==(const Version &p_other) const {
|
||||
return godot_api_hash == p_other.godot_api_hash;
|
||||
}
|
||||
|
||||
Version() {}
|
||||
|
||||
Version(uint64_t p_godot_api_hash) :
|
||||
godot_api_hash(p_godot_api_hash) {
|
||||
}
|
||||
|
||||
static Version get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, Type p_api_type);
|
||||
};
|
||||
|
||||
String to_string(Type p_type);
|
||||
} // namespace ApiAssemblyInfo
|
||||
|
||||
class GDMono {
|
||||
public:
|
||||
enum UnhandledExceptionPolicy {
|
||||
@@ -73,13 +48,6 @@ public:
|
||||
POLICY_LOG_ERROR
|
||||
};
|
||||
|
||||
struct LoadedApiAssembly {
|
||||
GDMonoAssembly *assembly = nullptr;
|
||||
bool out_of_sync = false;
|
||||
|
||||
LoadedApiAssembly() {}
|
||||
};
|
||||
|
||||
private:
|
||||
bool runtime_initialized;
|
||||
bool finalizing_scripts_domain;
|
||||
@@ -98,17 +66,12 @@ private:
|
||||
GDMonoAssembly *tools_project_editor_assembly = nullptr;
|
||||
#endif
|
||||
|
||||
LoadedApiAssembly core_api_assembly;
|
||||
LoadedApiAssembly editor_api_assembly;
|
||||
GDMonoAssembly *core_api_assembly;
|
||||
GDMonoAssembly *editor_api_assembly;
|
||||
|
||||
typedef bool (*CoreApiAssemblyLoadedCallback)();
|
||||
|
||||
bool _are_api_assemblies_out_of_sync();
|
||||
bool _temp_domain_load_are_assemblies_out_of_sync(const String &p_config);
|
||||
|
||||
bool _load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly);
|
||||
bool _load_core_api_assembly(GDMonoAssembly **r_loaded_api_assembly, const String &p_config);
|
||||
#ifdef TOOLS_ENABLED
|
||||
bool _load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly);
|
||||
bool _load_editor_api_assembly(GDMonoAssembly **r_loaded_api_assembly, const String &p_config);
|
||||
#endif
|
||||
|
||||
static bool _on_core_api_assembly_loaded();
|
||||
@@ -119,10 +82,7 @@ private:
|
||||
#endif
|
||||
bool _load_project_assembly();
|
||||
|
||||
bool _try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly,
|
||||
const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback);
|
||||
bool _try_load_api_assemblies_preset();
|
||||
void _load_api_assemblies();
|
||||
bool _try_load_api_assemblies();
|
||||
|
||||
void _install_trace_listener();
|
||||
|
||||
@@ -184,11 +144,6 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
bool copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config);
|
||||
String update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync = nullptr, const bool *p_editor_api_out_of_sync = nullptr);
|
||||
#endif
|
||||
|
||||
static GDMono *get_singleton() { return singleton; }
|
||||
|
||||
[[noreturn]] static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
|
||||
@@ -206,29 +161,24 @@ public:
|
||||
_FORCE_INLINE_ MonoDomain *get_scripts_domain() { return scripts_domain; }
|
||||
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_corlib_assembly() const { return corlib_assembly; }
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly.assembly; }
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly; }
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_project_assembly() const { return project_assembly; }
|
||||
#ifdef TOOLS_ENABLED
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_editor_api_assembly() const { return editor_api_assembly.assembly; }
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_tools_assembly() const { return tools_assembly; }
|
||||
_FORCE_INLINE_ GDMonoAssembly *get_tools_project_editor_assembly() const { return tools_project_editor_assembly; }
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
|
||||
const MonoRegInfo &get_mono_reg_info() { return mono_reg_info; }
|
||||
#endif
|
||||
|
||||
GDMonoClass *get_class(MonoClass *p_raw_class);
|
||||
GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name);
|
||||
|
||||
#ifdef GD_MONO_HOT_RELOAD
|
||||
Error reload_scripts_domain();
|
||||
#endif
|
||||
|
||||
bool load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly = false);
|
||||
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly = false);
|
||||
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly, const Vector<String> &p_search_dirs);
|
||||
bool load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly, bool p_refonly = false);
|
||||
bool load_assembly(const String &p_name, GDMonoAssembly **r_assembly);
|
||||
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly);
|
||||
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, const Vector<String> &p_search_dirs);
|
||||
bool load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly);
|
||||
|
||||
Error finalize_and_unload_domain(MonoDomain *p_domain);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user