diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 182970e18d5..5364f8ff797 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -65,17 +65,8 @@ #ifdef TOOLS_ENABLED static bool _create_project_solution_if_needed() { - String sln_path = GodotSharpDirs::get_project_sln_path(); - String csproj_path = GodotSharpDirs::get_project_csproj_path(); - - if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) { - // A solution does not yet exist, create a new one - - CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == nullptr); - return CSharpLanguage::get_singleton()->get_godotsharp_editor()->call("CreateProjectSolution"); - } - - return true; + CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == nullptr); + return CSharpLanguage::get_singleton()->get_godotsharp_editor()->call("CreateProjectSolutionIfNeeded"); } #endif @@ -107,7 +98,7 @@ Error CSharpLanguage::execute_file(const String &p_path) { extern void *godotsharp_pinvoke_funcs[186]; [[maybe_unused]] volatile void **do_not_strip_godotsharp_pinvoke_funcs; #ifdef TOOLS_ENABLED -extern void *godotsharp_editor_pinvoke_funcs[30]; +extern void *godotsharp_editor_pinvoke_funcs[28]; [[maybe_unused]] volatile void **do_not_strip_godotsharp_editor_pinvoke_funcs; #endif @@ -709,10 +700,14 @@ bool CSharpLanguage::is_assembly_reloading_needed() { return false; // Already up to date } } else { - String appname_safe = ProjectSettings::get_singleton()->get_safe_project_name(); + String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + + if (assembly_name.is_empty()) { + assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); + } assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir() - .plus_file(appname_safe + ".dll"); + .plus_file(assembly_name + ".dll"); assembly_path = ProjectSettings::get_singleton()->globalize_path(assembly_path); if (!FileAccess::exists(assembly_path)) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index e9718cc82c7..87549f61fea 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -289,7 +289,7 @@ MONO_AOT_MODE_LAST = 1000, // Archive the AOT object files into a static library var arFilePathsForAllArchs = new List(); - string projectAssemblyName = GodotSharpEditor.ProjectAssemblyName; + string projectAssemblyName = GodotSharpDirs.ProjectAssemblyName; foreach (var archPathsPair in objFilePathsForiOSArch) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 8d88734ead9..ecf363c106b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -141,9 +141,9 @@ namespace GodotTools.Export _ => "so" }; - if (!File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpEditor.ProjectAssemblyName}.dll")) + if (!File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.dll")) // NativeAOT shared library output - && !File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpEditor.ProjectAssemblyName}.{soExt}"))) + && !File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.{soExt}"))) { throw new NotSupportedException( "Publish succeeded but project assembly not found in the output directory"); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index dcc3f3db767..45a29d89de7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -40,19 +40,17 @@ namespace GodotTools public bool SkipBuildBeforePlaying { get; set; } = false; - public static string ProjectAssemblyName + [UsedImplicitly] + private bool CreateProjectSolutionIfNeeded() { - get + if (!File.Exists(GodotSharpDirs.ProjectSlnPath) || !File.Exists(GodotSharpDirs.ProjectCsProjPath)) { - string projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name"); - projectAssemblyName = projectAssemblyName.ToSafeDirName(); - if (string.IsNullOrEmpty(projectAssemblyName)) - projectAssemblyName = "UnnamedProject"; - return projectAssemblyName; + return CreateProjectSolution(); } + + return true; } - [UsedImplicitly] private bool CreateProjectSolution() { using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2)) @@ -62,7 +60,7 @@ namespace GodotTools string resourceDir = ProjectSettings.GlobalizePath("res://"); string path = resourceDir; - string name = ProjectAssemblyName; + string name = GodotSharpDirs.ProjectAssemblyName; string guid = CsProjOperations.GenerateGameProject(path, name); @@ -327,7 +325,8 @@ namespace GodotTools [UsedImplicitly] public bool OverridesExternalEditor() { - return (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None; + return (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor") != + ExternalEditorId.None; } public override bool _Build() @@ -348,7 +347,7 @@ namespace GodotTools // NOTE: The order in which changes are made to the project is important // Migrate to MSBuild project Sdks style if using the old style - ProjectUtils.MigrateToProjectSdksStyle(msbuildProject, ProjectAssemblyName); + ProjectUtils.MigrateToProjectSdksStyle(msbuildProject, GodotSharpDirs.ProjectAssemblyName); ProjectUtils.EnsureGodotSdkIsUpToDate(msbuildProject); @@ -412,6 +411,8 @@ namespace GodotTools _editorSettings = editorInterface.GetEditorSettings(); + GodotSharpDirs.RegisterProjectSettings(); + _errorDialog = new AcceptDialog(); editorBaseControl.AddChild(_errorDialog); diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs index 63c15e7d28d..14285cc0f1d 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs @@ -1,4 +1,8 @@ +using System.IO; +using Godot; using Godot.NativeInterop; +using GodotTools.Core; +using static GodotTools.Internals.Globals; namespace GodotTools.Internals { @@ -34,26 +38,6 @@ namespace GodotTools.Internals } } - public static string ProjectSlnPath - { - get - { - Internal.godot_icall_GodotSharpDirs_ProjectSlnPath(out godot_string dest); - using (dest) - return Marshaling.ConvertStringToManaged(dest); - } - } - - public static string ProjectCsProjPath - { - get - { - Internal.godot_icall_GodotSharpDirs_ProjectCsProjPath(out godot_string dest); - using (dest) - return Marshaling.ConvertStringToManaged(dest); - } - } - public static string DataEditorToolsDir { get @@ -63,5 +47,79 @@ namespace GodotTools.Internals return Marshaling.ConvertStringToManaged(dest); } } + + public static void RegisterProjectSettings() + { + GlobalDef("dotnet/project/assembly_name", ""); + GlobalDef("dotnet/project/solution_directory", ""); + GlobalDef("dotnet/project/c#_project_directory", ""); + } + + private static void DetermineProjectLocation() + { + static string DetermineProjectName() + { + string projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name"); + projectAssemblyName = projectAssemblyName.ToSafeDirName(); + if (string.IsNullOrEmpty(projectAssemblyName)) + projectAssemblyName = "UnnamedProject"; + return projectAssemblyName; + } + + _projectAssemblyName = (string)ProjectSettings.GetSetting("dotnet/project/assembly_name"); + if (string.IsNullOrEmpty(_projectAssemblyName)) + { + _projectAssemblyName = DetermineProjectName(); + ProjectSettings.SetSetting("dotnet/project/assembly_name", _projectAssemblyName); + } + + string slnParentDir = (string)ProjectSettings.GetSetting("dotnet/project/solution_directory"); + if (string.IsNullOrEmpty(slnParentDir)) + slnParentDir = "res://"; + + string csprojParentDir = (string)ProjectSettings.GetSetting("dotnet/project/c#_project_directory"); + if (string.IsNullOrEmpty(csprojParentDir)) + csprojParentDir = "res://"; + + _projectSlnPath = Path.Combine(ProjectSettings.GlobalizePath(slnParentDir), + string.Concat(_projectAssemblyName, ".sln")); + + _projectCsProjPath = Path.Combine(ProjectSettings.GlobalizePath(csprojParentDir), + string.Concat(_projectAssemblyName, ".csproj")); + } + + private static string _projectAssemblyName; + private static string _projectSlnPath; + private static string _projectCsProjPath; + + public static string ProjectAssemblyName + { + get + { + if (_projectAssemblyName == null) + DetermineProjectLocation(); + return _projectAssemblyName; + } + } + + public static string ProjectSlnPath + { + get + { + if (_projectSlnPath == null) + DetermineProjectLocation(); + return _projectSlnPath; + } + } + + public static string ProjectCsProjPath + { + get + { + if (_projectCsProjPath == null) + DetermineProjectLocation(); + return _projectCsProjPath; + } + } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index 00170a1ef77..f0d2bed2464 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -75,12 +75,6 @@ namespace GodotTools.Internals [DllImport(GodotDllName)] public static extern void godot_icall_GodotSharpDirs_BuildLogsDirs(out godot_string r_dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_ProjectSlnPath(out godot_string r_dest); - - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_ProjectCsProjPath(out godot_string r_dest); - [DllImport(GodotDllName)] public static extern void godot_icall_GodotSharpDirs_DataEditorToolsDir(out godot_string r_dest); diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 1544e61315e..bf0309126bf 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -86,22 +86,6 @@ GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_BuildLogsDirs(godot_string *r_ #endif } -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_ProjectSlnPath(godot_string *r_dest) { -#ifdef TOOLS_ENABLED - memnew_placement(r_dest, String(GodotSharpDirs::get_project_sln_path())); -#else - return nullptr; -#endif -} - -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_ProjectCsProjPath(godot_string *r_dest) { -#ifdef TOOLS_ENABLED - memnew_placement(r_dest, String(GodotSharpDirs::get_project_csproj_path())); -#else - return nullptr; -#endif -} - GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_DataEditorToolsDir(godot_string *r_dest) { #ifdef TOOLS_ENABLED memnew_placement(r_dest, String(GodotSharpDirs::get_data_editor_tools_dir())); @@ -253,12 +237,10 @@ GD_PINVOKE_EXPORT bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(const go } #endif -void *godotsharp_editor_pinvoke_funcs[30] = { +void *godotsharp_editor_pinvoke_funcs[28] = { (void *)godot_icall_GodotSharpDirs_ResMetadataDir, (void *)godot_icall_GodotSharpDirs_MonoUserDir, (void *)godot_icall_GodotSharpDirs_BuildLogsDirs, - (void *)godot_icall_GodotSharpDirs_ProjectSlnPath, - (void *)godot_icall_GodotSharpDirs_ProjectCsProjPath, (void *)godot_icall_GodotSharpDirs_DataEditorToolsDir, (void *)godot_icall_EditorProgress_Create, (void *)godot_icall_EditorProgress_Dispose, diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index f79a245d7d2..71576c2f806 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -110,9 +110,6 @@ public: String mono_solutions_dir; String build_logs_dir; - String sln_filepath; - String csproj_filepath; - String data_editor_tools_dir; #else // Equivalent of res_assemblies_dir, but in the data directory rather than in 'res://'. @@ -151,16 +148,7 @@ private: mono_solutions_dir = mono_user_dir.plus_file("solutions"); build_logs_dir = mono_user_dir.plus_file("build_logs"); - String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); - if (appname_safe.is_empty()) { - appname_safe = "UnnamedProject"; - } - String base_path = ProjectSettings::get_singleton()->globalize_path("res://"); - - sln_filepath = base_path.plus_file(appname_safe + ".sln"); - csproj_filepath = base_path.plus_file(appname_safe + ".csproj"); #endif String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir(); @@ -298,14 +286,6 @@ String get_build_logs_dir() { return _GodotSharpDirs::get_singleton().build_logs_dir; } -String get_project_sln_path() { - return _GodotSharpDirs::get_singleton().sln_filepath; -} - -String get_project_csproj_path() { - return _GodotSharpDirs::get_singleton().csproj_filepath; -} - String get_data_editor_tools_dir() { return _GodotSharpDirs::get_singleton().data_editor_tools_dir; } diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index 869991bb35c..03e62ffd822 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -52,9 +52,6 @@ String get_mono_logs_dir(); String get_mono_solutions_dir(); String get_build_logs_dir(); -String get_project_sln_path(); -String get_project_csproj_path(); - String get_data_editor_tools_dir(); #else String get_data_game_assemblies_dir(); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index b3ecee620fe..77c3f070096 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -329,13 +329,13 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime } #else static String get_assembly_name() { - String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); - if (appname_safe.is_empty()) { - appname_safe = "UnnamedProject"; + String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + + if (assembly_name.is_empty()) { + assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); } - return appname_safe; + return assembly_name; } godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime_initialized) { @@ -501,10 +501,14 @@ void GDMono::_init_godot_api_hashes() { #ifdef TOOLS_ENABLED bool GDMono::_load_project_assembly() { - String appname_safe = ProjectSettings::get_singleton()->get_safe_project_name(); + String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + + if (assembly_name.is_empty()) { + assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); + } String assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir() - .plus_file(appname_safe + ".dll"); + .plus_file(assembly_name + ".dll"); assembly_path = ProjectSettings::get_singleton()->globalize_path(assembly_path); String loaded_assembly_path;