using Nerfed.Runtime; namespace Nerfed.Editor.Project; internal static class EditorProject { internal static Compiler.Project Project { get; private set; } = null; internal static string ProjectFilePath { get; private set; } = string.Empty; internal static string ProjectSolutionFilePath { get; private set; } = string.Empty; internal static string ProjectDirectory { get; private set; } = string.Empty; internal static string ProjectContentDirectory { get; private set; } = string.Empty; internal static string ProjectTempDirectory { get; private set; } = string.Empty; private static readonly List<(string, EditorAssemblyLoader.EditorAssemblyLoadContextWrapper)> editorAssemblyLoadContextWrappers = []; internal static bool Create(string projectFilePath, string projectName) { Close(); if (!Compiler.Project.Create(projectFilePath, projectName, out Compiler.Project project)) { return false; } Open(projectFilePath); Log.Info($"Succesfully created project."); return true; } internal static bool Open(string projectFilePath) { Close(); if(!Compiler.Project.Open(projectFilePath, out Compiler.Project project)) { return false; } Project = project; ProjectFilePath = projectFilePath; ProjectDirectory = Path.GetDirectoryName(projectFilePath); string projectSolutionFilePath = Path.Combine(ProjectDirectory, Project.Name + Compiler.Generator.SolutionExtensionName); if (File.Exists(projectSolutionFilePath)) { ProjectSolutionFilePath = projectSolutionFilePath; } SetupDefaultFolders(); Compile(); Log.Info($"Opened project: {project.Name}"); return true; } internal static void Close() { Project = null; ProjectFilePath = string.Empty; ProjectSolutionFilePath = string.Empty; ProjectDirectory = string.Empty; ProjectContentDirectory = string.Empty; ProjectTempDirectory = string.Empty; } internal static bool Save() { if(Project == null) { return false; } return Compiler.Project.Save(Project, ProjectFilePath); } internal static void Compile() { if(Project == null) { return; } UnloadAssemblies(); Compiler.Compiler.Compile(ProjectFilePath, "Debug"); LoadAssemblies(); } internal static void GenerateSolution() { if(Project == null) { return; } Compiler.Generator.GenerateSolution(ProjectDirectory, Project, out string solutionFilePath); ProjectSolutionFilePath = solutionFilePath; } private static void SetupDefaultFolders() { if (Project == null || ProjectDirectory == null) { return; } string contentDirectory = Path.Combine(ProjectDirectory, "Content"); if (!Directory.Exists(contentDirectory)) { Directory.CreateDirectory(contentDirectory); } ProjectContentDirectory = contentDirectory; string scriptsDirectory = Path.Combine(ProjectContentDirectory, "Scripts"); if (!Directory.Exists(scriptsDirectory)) { Directory.CreateDirectory(scriptsDirectory); } string scriptsRuntimePath = Path.Combine(scriptsDirectory, "Runtime"); if (!Directory.Exists(scriptsRuntimePath)) { Directory.CreateDirectory(scriptsRuntimePath); } // Test create csproject. string gameplayRuntimeFilePath = Path.Combine(scriptsRuntimePath, Compiler.Generator.AssemblyDefinitionExtensionName); if (!File.Exists(gameplayRuntimeFilePath)) { Compiler.AssemblyDefinition.Create(gameplayRuntimeFilePath, "Gameplay", out Compiler.AssemblyDefinition project); } string tempDirectory = Path.Combine(ProjectDirectory, "Temp"); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } ProjectTempDirectory = tempDirectory; } private static void LoadAssemblies() { string[] assemblies = Directory.GetFiles(Path.Combine(ProjectDirectory, "bin"), "*.dll", SearchOption.AllDirectories); foreach (string assembly in assemblies) { (System.Reflection.Assembly, EditorAssemblyLoader.EditorAssemblyLoadContextWrapper) a = EditorAssemblyLoader.LoadFromPath(assembly); string name = a.Item1.GetName().Name; editorAssemblyLoadContextWrappers.Add((name, a.Item2)); Log.Info($"loaded {name}"); } Nerfed.Runtime.Generator.Hook.InvokeHooks(); } private static void UnloadAssemblies() { for (int i = editorAssemblyLoadContextWrappers.Count - 1; i >= 0; i--) { (string, EditorAssemblyLoader.EditorAssemblyLoadContextWrapper) a = editorAssemblyLoadContextWrappers[i]; if (EditorAssemblyLoader.Unload(a.Item2)) { Log.Info($"Unloaded {a.Item1}"); editorAssemblyLoadContextWrappers.RemoveAt(i); } else { Log.Error($"Could not unload {a.Item1}"); } } } }