Compare commits
	
		
			7 Commits
		
	
	
		
			91672d5760
			...
			project
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 09089c35b9 | |||
| bd76fc1b25 | |||
| d80cc51aff | |||
| ad2f527de5 | |||
| b4c3b5ed18 | |||
| b9f5a4c56b | |||
| 50a77d5120 | 
							
								
								
									
										64
									
								
								Nerfed.Compiler/AssemblyDefinition.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Nerfed.Compiler/AssemblyDefinition.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | using System.Text.Json; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Compiler; | ||||||
|  | 
 | ||||||
|  | public class AssemblyDefinition | ||||||
|  | { | ||||||
|  |     public string Name { get; set; } | ||||||
|  |     public string Guid { get; set; } | ||||||
|  |     //public bool IsEditor { get; set; } | ||||||
|  |     // Add platform stuff here..? | ||||||
|  |     // Add dll's here..? | ||||||
|  |     // Add dependencies here..? | ||||||
|  | 
 | ||||||
|  |     public static bool Create(string assemblyDefinitionFilePath, string name, out AssemblyDefinition assemblyDefinition) | ||||||
|  |     { | ||||||
|  |         assemblyDefinition = null; | ||||||
|  | 
 | ||||||
|  |         if (File.Exists(assemblyDefinitionFilePath)) | ||||||
|  |         { | ||||||
|  |             Console.WriteLine($"ERROR: File already exists!"); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Create project file. | ||||||
|  |         assemblyDefinition = new AssemblyDefinition | ||||||
|  |         { | ||||||
|  |             Name = name, | ||||||
|  |             Guid = System.Guid.NewGuid().ToString("B").ToUpper(), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         Save(assemblyDefinition, assemblyDefinitionFilePath); | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static bool Save(AssemblyDefinition assemblyDefinition, string assemblyDefinitionFilePath) | ||||||
|  |     { | ||||||
|  |         string jsonString = JsonSerializer.Serialize(assemblyDefinition, AssemblyDefinitionContext.Default.AssemblyDefinition); | ||||||
|  | 
 | ||||||
|  |         File.WriteAllText(assemblyDefinitionFilePath, jsonString); | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static bool Open(string assemblyDefinitionFilePath, out AssemblyDefinition assemblyDefinition) | ||||||
|  |     { | ||||||
|  |         string jsonString = File.ReadAllText(assemblyDefinitionFilePath); | ||||||
|  |         assemblyDefinition = JsonSerializer.Deserialize(jsonString, AssemblyDefinitionContext.Default.AssemblyDefinition); | ||||||
|  | 
 | ||||||
|  |         if (assemblyDefinition == null) | ||||||
|  |         { | ||||||
|  |             Console.WriteLine($"ERROR: Could not open {typeof(AssemblyDefinition)}."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [JsonSerializable(typeof(AssemblyDefinition))] | ||||||
|  | public partial class AssemblyDefinitionContext : JsonSerializerContext | ||||||
|  | { | ||||||
|  | } | ||||||
| @@ -1,64 +0,0 @@ | |||||||
| using System.Text.Json; |  | ||||||
| using System.Text.Json.Serialization; |  | ||||||
| 
 |  | ||||||
| namespace Nerfed.Compiler; |  | ||||||
| 
 |  | ||||||
| public class CSProject |  | ||||||
| { |  | ||||||
|     public string Name { get; set; } |  | ||||||
|     public string Guid { get; set; } |  | ||||||
|     //public bool IsEditor { get; set; } |  | ||||||
|     // Add platform stuff here..? |  | ||||||
|     // Add dll's here..? |  | ||||||
|     // Add dependencies here..? |  | ||||||
| 
 |  | ||||||
|     public static bool Create(string projectFilePath, string name, out CSProject project) |  | ||||||
|     { |  | ||||||
|         project = null; |  | ||||||
| 
 |  | ||||||
|         if (File.Exists(projectFilePath)) |  | ||||||
|         { |  | ||||||
|             Console.WriteLine($"ERROR: File already exists!"); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Create project file. |  | ||||||
|         project = new CSProject |  | ||||||
|         { |  | ||||||
|             Name = name, |  | ||||||
|             Guid = System.Guid.NewGuid().ToString("B").ToUpper(), |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         Save(project, projectFilePath); |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static bool Save(CSProject project, string projectFilePath) |  | ||||||
|     { |  | ||||||
|         string jsonString = JsonSerializer.Serialize(project, CSProjectContext.Default.CSProject); |  | ||||||
| 
 |  | ||||||
|         File.WriteAllText(projectFilePath, jsonString); |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static bool Open(string projectFilePath, out CSProject project) |  | ||||||
|     { |  | ||||||
|         string jsonString = File.ReadAllText(projectFilePath); |  | ||||||
|         project = JsonSerializer.Deserialize(jsonString, CSProjectContext.Default.CSProject); |  | ||||||
| 
 |  | ||||||
|         if (project == null) |  | ||||||
|         { |  | ||||||
|             Console.WriteLine($"ERROR: Could not open {typeof(CSProject)}."); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| [JsonSerializable(typeof(CSProject))] |  | ||||||
| public partial class CSProjectContext : JsonSerializerContext |  | ||||||
| { |  | ||||||
| } |  | ||||||
| @@ -1,23 +1,17 @@ | |||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Reflection; |  | ||||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||||
| using System.Text; |  | ||||||
| using System.Text.Json; |  | ||||||
| 
 | 
 | ||||||
| namespace Nerfed.Compiler; | namespace Nerfed.Compiler; | ||||||
| 
 | 
 | ||||||
| public static class Compiler | public static class Compiler | ||||||
| { | { | ||||||
|     public const string CSProjectFileName = ".csproject"; |  | ||||||
|     public const string CSProjFileName = ".csproj"; |  | ||||||
| 
 |  | ||||||
|     public static bool Compile(string projectFilePath, string configuration = "Debug") |     public static bool Compile(string projectFilePath, string configuration = "Debug") | ||||||
|     { |     { | ||||||
|         string projectPath = Path.GetDirectoryName(projectFilePath); |         string projectDirectory = Path.GetDirectoryName(projectFilePath); | ||||||
| 
 | 
 | ||||||
|         if (!File.Exists(projectFilePath)) |         if (!File.Exists(projectFilePath)) | ||||||
|         { |         { | ||||||
|             Console.WriteLine($"ERROR: Project file not found at {projectPath}."); |             Console.WriteLine($"ERROR: Project file not found at {projectDirectory}."); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @@ -29,7 +23,7 @@ public static class Compiler | |||||||
|         // TODO: Check project version, to make sure we can compile it or something... |         // TODO: Check project version, to make sure we can compile it or something... | ||||||
| 
 | 
 | ||||||
|         // Generate solution. |         // Generate solution. | ||||||
|         GenerateSolution(projectPath, project, out string solutionFilePath); |         Generator.GenerateSolution(projectDirectory, project, out string solutionFilePath); | ||||||
| 
 | 
 | ||||||
|         // Compile solution. |         // Compile solution. | ||||||
|         ProcessStartInfo processInfo = new() |         ProcessStartInfo processInfo = new() | ||||||
| @@ -85,147 +79,4 @@ public static class Compiler | |||||||
| 
 | 
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     public static void GenerateSolution(string projectPath, Project project, out string solutionPath) |  | ||||||
|     { |  | ||||||
|         // Clear files. |  | ||||||
|         string[] csProjectFiles = Directory.GetFiles(projectPath, $"*{CSProjFileName}", SearchOption.TopDirectoryOnly); |  | ||||||
|         foreach (string csProjFile in csProjectFiles) |  | ||||||
|         { |  | ||||||
|             File.Delete(csProjFile); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Generate projects. |  | ||||||
|         string[] csProjectFilePaths = Directory.GetFiles(projectPath, CSProjectFileName, SearchOption.AllDirectories); |  | ||||||
|         foreach (string csProjectFilePath in csProjectFilePaths) |  | ||||||
|         { |  | ||||||
|             GenerateCSProject(csProjectFilePath, projectPath); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Generate solution. |  | ||||||
|         string[] csProjPaths = Directory.GetFiles(projectPath, $"*{CSProjFileName}", SearchOption.TopDirectoryOnly); |  | ||||||
|         string[] csProjGuids = new string[csProjPaths.Length]; |  | ||||||
|         for (int i = 0; i < csProjPaths.Length; i++) |  | ||||||
|         { |  | ||||||
|             csProjGuids[i] = Guid.NewGuid().ToString("B").ToUpper(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         StringBuilder solutionContent = new StringBuilder(); |  | ||||||
| 
 |  | ||||||
|         // Write the solution file header |  | ||||||
|         solutionContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); |  | ||||||
|         solutionContent.AppendLine("# Visual Studio Version 17"); |  | ||||||
|         solutionContent.AppendLine("VisualStudioVersion = 17.10.35013.160"); |  | ||||||
|         solutionContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); |  | ||||||
| 
 |  | ||||||
|         // Add each project to the solution file |  | ||||||
|         for (int i = 0; i < csProjPaths.Length; i++) |  | ||||||
|         { |  | ||||||
|             string csProjPath = csProjPaths[i]; |  | ||||||
|             string projectGuid = csProjGuids[i]; |  | ||||||
|             string projectName = Path.GetFileNameWithoutExtension(csProjPath); |  | ||||||
|             string projectRelativePath = Path.GetRelativePath(projectPath, csProjPath); |  | ||||||
|             // FAE04EC0-301F-11D3-BF4B-00C04F79EFBC for C# projects. |  | ||||||
|             solutionContent.AppendLine($"Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{projectName}\", \"{projectRelativePath}\", \"{projectGuid}\""); |  | ||||||
|             solutionContent.AppendLine("EndProject"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Add global sections (these can be extended as needed) |  | ||||||
|         solutionContent.AppendLine("Global"); |  | ||||||
|         solutionContent.AppendLine("	GlobalSection(SolutionConfigurationPlatforms) = preSolution"); |  | ||||||
|         solutionContent.AppendLine("		Test|x64 = Test|x64"); |  | ||||||
|         solutionContent.AppendLine("		Release|x64 = Release|x64"); |  | ||||||
|         solutionContent.AppendLine("		Debug|x64 = Debug|x64"); |  | ||||||
|         solutionContent.AppendLine("	EndGlobalSection"); |  | ||||||
|         solutionContent.AppendLine("	GlobalSection(ProjectConfigurationPlatforms) = postSolution"); |  | ||||||
| 
 |  | ||||||
|         for (int i = 0; i < csProjPaths.Length; i++) |  | ||||||
|         { |  | ||||||
|             string projectGuid = csProjGuids[i]; |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Test|x64.ActiveCfg = Test|x64"); |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Test|x64.Build.0 = Test|x64"); |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Release|x64.ActiveCfg = Release|x64"); |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Release|x64.Build.0 = Release|x64"); |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Debug|x64.ActiveCfg = Debug|x64"); |  | ||||||
|             solutionContent.AppendLine($"		{projectGuid}.Debug|x64.Build.0 = Debug|x64"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         solutionContent.AppendLine("	EndGlobalSection"); |  | ||||||
|         solutionContent.AppendLine("	GlobalSection(SolutionProperties) = preSolution"); |  | ||||||
|         solutionContent.AppendLine("		HideSolutionNode = FALSE"); |  | ||||||
|         solutionContent.AppendLine("	EndGlobalSection"); |  | ||||||
|         solutionContent.AppendLine("EndGlobal"); |  | ||||||
| 
 |  | ||||||
|         // Write the solution file content to disk |  | ||||||
|         string solutionName = project.Name + ".sln"; |  | ||||||
|         string filePath = Path.Combine(projectPath, solutionName); |  | ||||||
|         File.WriteAllText(filePath, solutionContent.ToString()); |  | ||||||
| 
 |  | ||||||
|         solutionPath = filePath; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void GenerateCSProject(string csProjectFilePath, string projectPath) |  | ||||||
|     { |  | ||||||
|         if (!File.Exists(csProjectFilePath)) |  | ||||||
|         { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         string jsonString = File.ReadAllText(csProjectFilePath); |  | ||||||
|         CSProject csProject = JsonSerializer.Deserialize(jsonString, CSProjectContext.Default.CSProject); |  | ||||||
| 
 |  | ||||||
|         Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); |  | ||||||
|         Assembly runtimeAssembly = loadedAssemblies.FirstOrDefault(assembly => assembly.GetName().Name == "Nerfed.Runtime") ?? throw new Exception("Failed to find Runtime Assembly!"); |  | ||||||
| 
 |  | ||||||
|         // TODO: get all dependencies. |  | ||||||
|         // TODO: properly get assemblies. |  | ||||||
| 
 |  | ||||||
|         StringBuilder projectContent = new StringBuilder(); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk\">"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <PropertyGroup>"); |  | ||||||
|         projectContent.AppendLine("     <TargetFramework>net8.0</TargetFramework>"); |  | ||||||
|         projectContent.AppendLine("     <ImplicitUsings>enable</ImplicitUsings>"); |  | ||||||
|         projectContent.AppendLine("     <Nullable>disable</Nullable>"); |  | ||||||
|         projectContent.AppendLine("     <PublishAot>true</PublishAot>"); |  | ||||||
|         projectContent.AppendLine("     <InvariantGlobalization>true</InvariantGlobalization>"); |  | ||||||
|         projectContent.AppendLine("     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>"); |  | ||||||
|         projectContent.AppendLine("     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>"); |  | ||||||
|         projectContent.AppendLine("     <IsPackable>false</IsPackable>"); |  | ||||||
|         projectContent.AppendLine("     <Configurations>Debug;Test;Release</Configurations>"); |  | ||||||
|         projectContent.AppendLine("     <Platforms>x64</Platforms>"); |  | ||||||
|         projectContent.AppendLine(" </PropertyGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|x64' \">"); |  | ||||||
|         projectContent.AppendLine("     <DefineConstants>TRACE;LOG_INFO;PROFILING</DefineConstants>"); |  | ||||||
|         projectContent.AppendLine(" </PropertyGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Test|x64' \">"); |  | ||||||
|         projectContent.AppendLine("     <DefineConstants>TRACE;LOG_ERROR;PROFILING</DefineConstants>"); |  | ||||||
|         projectContent.AppendLine("     <Optimize>true</Optimize>"); |  | ||||||
|         projectContent.AppendLine(" </PropertyGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|x64' \">"); |  | ||||||
|         projectContent.AppendLine("     <DefineConstants>TRACE;LOG_ERROR</DefineConstants>"); |  | ||||||
|         projectContent.AppendLine("     <Optimize>true</Optimize>"); |  | ||||||
|         projectContent.AppendLine(" </PropertyGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <ItemGroup>"); |  | ||||||
|         projectContent.AppendLine($"     <Compile Include=\"{csProjectFilePath}/**/*.cs\"/>"); |  | ||||||
|         projectContent.AppendLine(" </ItemGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine(" <ItemGroup>"); |  | ||||||
|         projectContent.AppendLine("     <Reference Include=\"Nerfed.Runtime\">"); |  | ||||||
|         projectContent.AppendLine($"         <HintPath>{runtimeAssembly.Location}</HintPath>"); |  | ||||||
|         projectContent.AppendLine("         <Private>false</Private>"); |  | ||||||
|         projectContent.AppendLine("     </Reference>"); |  | ||||||
|         projectContent.AppendLine(" </ItemGroup>"); |  | ||||||
| 
 |  | ||||||
|         projectContent.AppendLine("</Project>"); |  | ||||||
| 
 |  | ||||||
|         string projectName = csProject.Name + ".csproj"; |  | ||||||
|         string filePath = Path.Combine(projectPath, projectName); |  | ||||||
|         File.WriteAllText(filePath, projectContent.ToString()); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
							
								
								
									
										161
									
								
								Nerfed.Compiler/Generator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								Nerfed.Compiler/Generator.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | |||||||
|  | using System.Reflection; | ||||||
|  | using System.Text; | ||||||
|  | using System.Text.Json; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Compiler; | ||||||
|  | 
 | ||||||
|  | public static class Generator | ||||||
|  | { | ||||||
|  |     public const string AssemblyDefinitionExtensionName = ".asmdef"; | ||||||
|  |     public const string CSProjectExtensionName = ".csproj"; | ||||||
|  |     public const string SolutionExtensionName = ".sln"; | ||||||
|  | 
 | ||||||
|  |     public static void GenerateSolution(string projectDirectory, Project project, out string solutionFilePath) | ||||||
|  |     { | ||||||
|  |         // Clear files. | ||||||
|  |         ClearCSProjectFiles(projectDirectory); | ||||||
|  | 
 | ||||||
|  |         // Generate projects. | ||||||
|  |         string[] assemblyDefinitionFilePaths = Directory.GetFiles(projectDirectory, AssemblyDefinitionExtensionName, SearchOption.AllDirectories); | ||||||
|  |         foreach (string assemblyDefinitionFilePath in assemblyDefinitionFilePaths) | ||||||
|  |         { | ||||||
|  |             GenerateCSProject(assemblyDefinitionFilePath, projectDirectory, out string csProjectFilePath); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Generate solution. | ||||||
|  |         string[] csProjectPaths = Directory.GetFiles(projectDirectory, $"*{CSProjectExtensionName}", SearchOption.TopDirectoryOnly); | ||||||
|  |         string[] csProjectGuids = new string[csProjectPaths.Length]; | ||||||
|  |         for (int i = 0; i < csProjectPaths.Length; i++) | ||||||
|  |         { | ||||||
|  |             csProjectGuids[i] = Guid.NewGuid().ToString("B").ToUpper(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         StringBuilder content = new StringBuilder(); | ||||||
|  | 
 | ||||||
|  |         // Write the solution file header | ||||||
|  |         content.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); | ||||||
|  |         content.AppendLine("# Visual Studio Version 17"); | ||||||
|  |         content.AppendLine("VisualStudioVersion = 17.10.35013.160"); | ||||||
|  |         content.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); | ||||||
|  | 
 | ||||||
|  |         // Add each project to the solution file | ||||||
|  |         for (int i = 0; i < csProjectPaths.Length; i++) | ||||||
|  |         { | ||||||
|  |             string csProjectPath = csProjectPaths[i]; | ||||||
|  |             string csProjectGuid = csProjectGuids[i]; | ||||||
|  |             string csProjectName = Path.GetFileNameWithoutExtension(csProjectPath); | ||||||
|  |             string csProjectRelativePath = Path.GetRelativePath(projectDirectory, csProjectPath); | ||||||
|  |             // FAE04EC0-301F-11D3-BF4B-00C04F79EFBC for C# projects. | ||||||
|  |             content.AppendLine($"Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{csProjectName}\", \"{csProjectRelativePath}\", \"{csProjectGuid}\""); | ||||||
|  |             content.AppendLine("EndProject"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Add global sections (these can be extended as needed) | ||||||
|  |         content.AppendLine("Global"); | ||||||
|  |         content.AppendLine("	GlobalSection(SolutionConfigurationPlatforms) = preSolution"); | ||||||
|  |         content.AppendLine("		Test|x64 = Test|x64"); | ||||||
|  |         content.AppendLine("		Release|x64 = Release|x64"); | ||||||
|  |         content.AppendLine("		Debug|x64 = Debug|x64"); | ||||||
|  |         content.AppendLine("	EndGlobalSection"); | ||||||
|  |         content.AppendLine("	GlobalSection(ProjectConfigurationPlatforms) = postSolution"); | ||||||
|  | 
 | ||||||
|  |         for (int i = 0; i < csProjectPaths.Length; i++) | ||||||
|  |         { | ||||||
|  |             string projectGuid = csProjectGuids[i]; | ||||||
|  |             content.AppendLine($"		{projectGuid}.Test|x64.ActiveCfg = Test|x64"); | ||||||
|  |             content.AppendLine($"		{projectGuid}.Test|x64.Build.0 = Test|x64"); | ||||||
|  |             content.AppendLine($"		{projectGuid}.Release|x64.ActiveCfg = Release|x64"); | ||||||
|  |             content.AppendLine($"		{projectGuid}.Release|x64.Build.0 = Release|x64"); | ||||||
|  |             content.AppendLine($"		{projectGuid}.Debug|x64.ActiveCfg = Debug|x64"); | ||||||
|  |             content.AppendLine($"		{projectGuid}.Debug|x64.Build.0 = Debug|x64"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         content.AppendLine("	EndGlobalSection"); | ||||||
|  |         content.AppendLine("	GlobalSection(SolutionProperties) = preSolution"); | ||||||
|  |         content.AppendLine("		HideSolutionNode = FALSE"); | ||||||
|  |         content.AppendLine("	EndGlobalSection"); | ||||||
|  |         content.AppendLine("EndGlobal"); | ||||||
|  | 
 | ||||||
|  |         // Write the solution file content to disk | ||||||
|  |         string solutionName = project.Name + SolutionExtensionName; | ||||||
|  |         solutionFilePath = Path.Combine(projectDirectory, solutionName); | ||||||
|  |         File.WriteAllText(solutionFilePath, content.ToString()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static bool GenerateCSProject(string assemblyDefinitionFilePath, string projectPath, out string csProjectFilePath) | ||||||
|  |     { | ||||||
|  |         if (!File.Exists(assemblyDefinitionFilePath)) | ||||||
|  |         { | ||||||
|  |             csProjectFilePath = string.Empty; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         string jsonString = File.ReadAllText(assemblyDefinitionFilePath); | ||||||
|  |         AssemblyDefinition assemblyDefinition = JsonSerializer.Deserialize(jsonString, AssemblyDefinitionContext.Default.AssemblyDefinition); | ||||||
|  | 
 | ||||||
|  |         Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); | ||||||
|  |         Assembly runtimeAssembly = loadedAssemblies.FirstOrDefault(assembly => assembly.GetName().Name == "Nerfed.Runtime") ?? throw new Exception("Failed to find Runtime Assembly!"); | ||||||
|  | 
 | ||||||
|  |         // TODO: get all dependencies. | ||||||
|  |         // TODO: properly get assemblies. | ||||||
|  | 
 | ||||||
|  |         StringBuilder content = new StringBuilder(); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk\">"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <PropertyGroup>"); | ||||||
|  |         content.AppendLine("     <TargetFramework>net8.0</TargetFramework>"); | ||||||
|  |         content.AppendLine("     <ImplicitUsings>enable</ImplicitUsings>"); | ||||||
|  |         content.AppendLine("     <Nullable>disable</Nullable>"); | ||||||
|  |         content.AppendLine("     <PublishAot>true</PublishAot>"); | ||||||
|  |         content.AppendLine("     <InvariantGlobalization>true</InvariantGlobalization>"); | ||||||
|  |         content.AppendLine("     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>"); | ||||||
|  |         content.AppendLine("     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>"); | ||||||
|  |         content.AppendLine("     <IsPackable>false</IsPackable>"); | ||||||
|  |         content.AppendLine("     <Configurations>Debug;Test;Release</Configurations>"); | ||||||
|  |         content.AppendLine("     <Platforms>x64</Platforms>"); | ||||||
|  |         content.AppendLine(" </PropertyGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|x64' \">"); | ||||||
|  |         content.AppendLine("     <DefineConstants>TRACE;LOG_INFO;PROFILING</DefineConstants>"); | ||||||
|  |         content.AppendLine(" </PropertyGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Test|x64' \">"); | ||||||
|  |         content.AppendLine("     <DefineConstants>TRACE;LOG_ERROR;PROFILING</DefineConstants>"); | ||||||
|  |         content.AppendLine("     <Optimize>true</Optimize>"); | ||||||
|  |         content.AppendLine(" </PropertyGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|x64' \">"); | ||||||
|  |         content.AppendLine("     <DefineConstants>TRACE;LOG_ERROR</DefineConstants>"); | ||||||
|  |         content.AppendLine("     <Optimize>true</Optimize>"); | ||||||
|  |         content.AppendLine(" </PropertyGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <ItemGroup>"); | ||||||
|  |         content.AppendLine($"     <Compile Include=\"{assemblyDefinitionFilePath}/**/*.cs\"/>"); | ||||||
|  |         content.AppendLine(" </ItemGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine(" <ItemGroup>"); | ||||||
|  |         content.AppendLine("     <Reference Include=\"Nerfed.Runtime\">"); | ||||||
|  |         content.AppendLine($"         <HintPath>{runtimeAssembly.Location}</HintPath>"); | ||||||
|  |         content.AppendLine("         <Private>false</Private>"); | ||||||
|  |         content.AppendLine("     </Reference>"); | ||||||
|  |         content.AppendLine(" </ItemGroup>"); | ||||||
|  | 
 | ||||||
|  |         content.AppendLine("</Project>"); | ||||||
|  | 
 | ||||||
|  |         string csProjectName = assemblyDefinition.Name + CSProjectExtensionName; | ||||||
|  |         csProjectFilePath = Path.Combine(projectPath, csProjectName); | ||||||
|  |         File.WriteAllText(csProjectFilePath, content.ToString()); | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static void ClearCSProjectFiles(string projectPath) | ||||||
|  |     { | ||||||
|  |         string[] csProjectFiles = Directory.GetFiles(projectPath, $"*{CSProjectExtensionName}", SearchOption.TopDirectoryOnly); | ||||||
|  |         foreach (string csProjectFile in csProjectFiles) | ||||||
|  |         { | ||||||
|  |             File.Delete(csProjectFile); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,10 +1,15 @@ | |||||||
| namespace Nerfed.Compiler | namespace Nerfed.Compiler; | ||||||
|  | 
 | ||||||
|  | public class Program | ||||||
| { | { | ||||||
|     public class Program |  | ||||||
|     { |  | ||||||
|     internal static void Main(string[] args) |     internal static void Main(string[] args) | ||||||
|     { |     { | ||||||
|  |         if (args.Length != 2) | ||||||
|  |         { | ||||||
|  |             Console.WriteLine("projectFilePath, configuration (Debug, Test, Release)"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         Compiler.Compile(args[0], args[1]); |         Compiler.Compile(args[0], args[1]); | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| } | } | ||||||
| @@ -69,7 +69,7 @@ namespace Nerfed.Editor | |||||||
| 
 | 
 | ||||||
|             ImGui.ShowDemoWindow(); |             ImGui.ShowDemoWindow(); | ||||||
| 
 | 
 | ||||||
|             ProjectGui.OnGui(); |             EditorProjectGui.OnGui(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										8
									
								
								Nerfed.Editor/Project/EditorAssemblyLoadContext.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Nerfed.Editor/Project/EditorAssemblyLoadContext.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | using System.Runtime.Loader; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Editor.Project; | ||||||
|  | 
 | ||||||
|  | internal class EditorAssemblyLoadContext : AssemblyLoadContext | ||||||
|  | { | ||||||
|  |     public EditorAssemblyLoadContext() : base(isCollectible: true) { } | ||||||
|  | } | ||||||
							
								
								
									
										124
									
								
								Nerfed.Editor/Project/EditorAssemblyLoader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								Nerfed.Editor/Project/EditorAssemblyLoader.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | using Nerfed.Runtime; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Runtime.CompilerServices; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Editor.Project; | ||||||
|  | 
 | ||||||
|  | // https://github.com/godotengine/godot/blob/master/modules/mono/glue/GodotSharp/GodotPlugins/Main.c | ||||||
|  | // https://gitlab.com/robertk92/assemblyreloadtest/-/blob/main/AppContextTest/Program.cs | ||||||
|  | 
 | ||||||
|  | internal static class EditorAssemblyLoader | ||||||
|  | { | ||||||
|  |     internal sealed class EditorAssemblyLoadContextWrapper | ||||||
|  |     { | ||||||
|  |         private EditorAssemblyLoadContext assemblyLoadContext; | ||||||
|  |         private readonly WeakReference weakReference; | ||||||
|  | 
 | ||||||
|  |         private EditorAssemblyLoadContextWrapper(EditorAssemblyLoadContext assemblyLoadContext, WeakReference weakReference) | ||||||
|  |         { | ||||||
|  |             this.assemblyLoadContext = assemblyLoadContext; | ||||||
|  |             this.weakReference = weakReference; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public bool IsCollectible | ||||||
|  |         { | ||||||
|  |             [MethodImpl(MethodImplOptions.NoInlining)] | ||||||
|  |             // If assemblyLoadContext is null we already started unloading, so it was collectible. | ||||||
|  |             get => assemblyLoadContext?.IsCollectible ?? true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public bool IsAlive | ||||||
|  |         { | ||||||
|  |             [MethodImpl(MethodImplOptions.NoInlining)] | ||||||
|  |             get => weakReference.IsAlive; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [MethodImpl(MethodImplOptions.NoInlining)] | ||||||
|  |         public static (Assembly, EditorAssemblyLoadContextWrapper) CreateAndLoad(AssemblyName assemblyName) | ||||||
|  |         { | ||||||
|  |             EditorAssemblyLoadContext context = new EditorAssemblyLoadContext(); | ||||||
|  |             WeakReference reference = new WeakReference(context, trackResurrection: true); | ||||||
|  |             EditorAssemblyLoadContextWrapper wrapper = new EditorAssemblyLoadContextWrapper(context, reference); | ||||||
|  |             Assembly assembly = context.LoadFromAssemblyName(assemblyName); | ||||||
|  |             return (assembly, wrapper); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [MethodImpl(MethodImplOptions.NoInlining)] | ||||||
|  |         public static (Assembly, EditorAssemblyLoadContextWrapper) CreateAndLoad(string assemblyPath) | ||||||
|  |         { | ||||||
|  |             EditorAssemblyLoadContext context = new EditorAssemblyLoadContext(); | ||||||
|  |             WeakReference reference = new WeakReference(context, trackResurrection: true); | ||||||
|  |             EditorAssemblyLoadContextWrapper wrapper = new EditorAssemblyLoadContextWrapper(context, reference); | ||||||
|  |             Assembly assembly = context.LoadFromAssemblyPath(assemblyPath); | ||||||
|  |             return (assembly, wrapper); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [MethodImpl(MethodImplOptions.NoInlining)] | ||||||
|  |         internal void Unload() | ||||||
|  |         { | ||||||
|  |             assemblyLoadContext?.Unload(); | ||||||
|  |             assemblyLoadContext = null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     internal static (Assembly, EditorAssemblyLoadContextWrapper) Load(string assemblyFilePath) | ||||||
|  |     { | ||||||
|  |         string assemblyFileName = Path.GetFileNameWithoutExtension(assemblyFilePath); | ||||||
|  | 
 | ||||||
|  |         AssemblyName assemblyName = new AssemblyName(assemblyFileName); | ||||||
|  | 
 | ||||||
|  |         return EditorAssemblyLoadContextWrapper.CreateAndLoad(assemblyName); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     internal static (Assembly, EditorAssemblyLoadContextWrapper) LoadFromPath(string assemblyFilePath) | ||||||
|  |     { | ||||||
|  |         return EditorAssemblyLoadContextWrapper.CreateAndLoad(assemblyFilePath); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     internal static bool Unload(EditorAssemblyLoadContextWrapper assemblyLoadContextWrapper) | ||||||
|  |     { | ||||||
|  |         if (assemblyLoadContextWrapper == null) | ||||||
|  |         { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!assemblyLoadContextWrapper.IsCollectible)  | ||||||
|  |         { | ||||||
|  |             Log.Error($"{assemblyLoadContextWrapper} is not collectable!"); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assemblyLoadContextWrapper.Unload(); | ||||||
|  | 
 | ||||||
|  |         GC.Collect(); | ||||||
|  |         GC.WaitForPendingFinalizers(); | ||||||
|  | 
 | ||||||
|  |         TimeSpan timeout = TimeSpan.FromSeconds(30); | ||||||
|  |         Stopwatch stopwatch = Stopwatch.StartNew(); | ||||||
|  | 
 | ||||||
|  |         while (assemblyLoadContextWrapper.IsAlive)  | ||||||
|  |         { | ||||||
|  |             GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); | ||||||
|  |             GC.WaitForPendingFinalizers(); | ||||||
|  | 
 | ||||||
|  |             if (!assemblyLoadContextWrapper.IsAlive) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (stopwatch.Elapsed.TotalSeconds % 10 == 0) | ||||||
|  |             { | ||||||
|  |                 Log.Info("Tring to unload assembly..."); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (stopwatch.Elapsed >= timeout) | ||||||
|  |             { | ||||||
|  |                 Log.Error("Failed to unload assembly!"); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										173
									
								
								Nerfed.Editor/Project/EditorProject.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								Nerfed.Editor/Project/EditorProject.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | |||||||
|  | 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}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								Nerfed.Editor/Project/EditorProjectGui.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Nerfed.Editor/Project/EditorProjectGui.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | using ImGuiNET; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Editor.Project; | ||||||
|  | 
 | ||||||
|  | internal static class EditorProjectGui | ||||||
|  | { | ||||||
|  |     private static string projectDirectory = string.Empty; | ||||||
|  |     private static string projectName = string.Empty; | ||||||
|  |     private static string projectFilePath = string.Empty; | ||||||
|  | 
 | ||||||
|  |     internal static void OnGui() | ||||||
|  |     { | ||||||
|  |         ImGui.Begin("Project"); | ||||||
|  |         ImGui.BeginGroup(); | ||||||
|  | 
 | ||||||
|  |         ImGui.InputText("Project Directory", ref projectDirectory, 512); | ||||||
|  |         ImGui.InputText("Project Name", ref projectName, 512); | ||||||
|  | 
 | ||||||
|  |         string newProjectFilePath = Path.Combine(projectDirectory, ".project"); | ||||||
|  |         ImGui.Text(newProjectFilePath); | ||||||
|  | 
 | ||||||
|  |         if (ImGui.Button("Create Project")) | ||||||
|  |         { | ||||||
|  |             EditorProject.Create(newProjectFilePath, projectName); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ImGui.EndGroup(); | ||||||
|  |         ImGui.BeginGroup(); | ||||||
|  | 
 | ||||||
|  |         ImGui.InputText("Project File Path", ref projectFilePath, 512); | ||||||
|  |         if (ImGui.Button("Open Project")) | ||||||
|  |         { | ||||||
|  |             EditorProject.Open(projectFilePath); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ImGui.Text("Loaded project: "); | ||||||
|  |         if(EditorProject.Project != null) | ||||||
|  |         { | ||||||
|  |             ImGui.Text(EditorProject.Project.Name); | ||||||
|  |             ImGui.Text(EditorProject.ProjectFilePath); | ||||||
|  |             ImGui.Text(EditorProject.ProjectSolutionFilePath); | ||||||
|  |             ImGui.Text(EditorProject.ProjectDirectory); | ||||||
|  |             ImGui.Text(EditorProject.ProjectContentDirectory); | ||||||
|  |             ImGui.Text(EditorProject.ProjectTempDirectory); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             ImGui.Text("None"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ImGui.EndGroup(); | ||||||
|  |         ImGui.BeginGroup(); | ||||||
|  | 
 | ||||||
|  |         if (ImGui.Button("Generate Solution")) | ||||||
|  |         { | ||||||
|  |             EditorProject.GenerateSolution(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (ImGui.Button("Compile")) | ||||||
|  |         { | ||||||
|  |             EditorProject.Compile(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ImGui.EndGroup(); | ||||||
|  |         ImGui.End(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,135 +0,0 @@ | |||||||
| using Nerfed.Runtime; |  | ||||||
| 
 |  | ||||||
| namespace Nerfed.Editor.Project; |  | ||||||
| 
 |  | ||||||
| internal static class EditorProject |  | ||||||
| { |  | ||||||
|     internal static Compiler.Project Project { get; private set; } |  | ||||||
|     internal static string ProjectFilePath { get; private set; } |  | ||||||
|     internal static string ProjectSolutionFilePath { get; private set; } |  | ||||||
|     internal static string ProjectPath { get; private set; } |  | ||||||
|     internal static string ProjectContentPath { get; private set; } |  | ||||||
|     internal static string ProjectTempPath { get; private set; } |  | ||||||
| 
 |  | ||||||
|     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 path) |  | ||||||
|     { |  | ||||||
|         Close(); |  | ||||||
| 
 |  | ||||||
|         if(!Compiler.Project.Open(path, out Compiler.Project project)) |  | ||||||
|         { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Project = project; |  | ||||||
|         ProjectFilePath = path; |  | ||||||
|         ProjectPath = Path.GetDirectoryName(path); |  | ||||||
| 
 |  | ||||||
|         string projectSolutionFilePath = Path.Combine(ProjectPath, Project.Name + ".sln"); |  | ||||||
|         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; |  | ||||||
|         ProjectPath = string.Empty; |  | ||||||
|         ProjectContentPath = string.Empty; |  | ||||||
|         ProjectTempPath = 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; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Nerfed.Compiler.Compiler.Compile(ProjectFilePath, "Debug"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     internal static void GenerateSolution() |  | ||||||
|     { |  | ||||||
|         if(Project == null) |  | ||||||
|         { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Nerfed.Compiler.Compiler.GenerateSolution(ProjectPath, Project, out string solutionFilePath); |  | ||||||
|         ProjectSolutionFilePath = solutionFilePath; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void SetupDefaultFolders() |  | ||||||
|     { |  | ||||||
|         if (Project == null || ProjectPath == null) |  | ||||||
|         { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         string contentPath = Path.Combine(ProjectPath, "Content"); |  | ||||||
|         if (!Directory.Exists(contentPath)) |  | ||||||
|         { |  | ||||||
|             Directory.CreateDirectory(contentPath); |  | ||||||
|         } |  | ||||||
|         ProjectContentPath = contentPath; |  | ||||||
|         string scriptsPath = Path.Combine(ProjectContentPath, "Scripts"); |  | ||||||
|         if (!Directory.Exists(scriptsPath)) |  | ||||||
|         { |  | ||||||
|             Directory.CreateDirectory(scriptsPath); |  | ||||||
|         } |  | ||||||
|         string scriptsRuntimePath = Path.Combine(scriptsPath, "Runtime"); |  | ||||||
|         if (!Directory.Exists(scriptsRuntimePath)) |  | ||||||
|         { |  | ||||||
|             Directory.CreateDirectory(scriptsRuntimePath); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Test create csproject. |  | ||||||
|         string gameplayRuntimePath = Path.Combine(scriptsRuntimePath, ".csproject"); |  | ||||||
|         if (!File.Exists(gameplayRuntimePath)) |  | ||||||
|         { |  | ||||||
|             Compiler.CSProject.Create(gameplayRuntimePath, "Gameplay", out Compiler.CSProject project); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         string tempPath = Path.Combine(ProjectPath, "Temp"); |  | ||||||
|         if (!Directory.Exists(tempPath)) |  | ||||||
|         { |  | ||||||
|             Directory.CreateDirectory(tempPath); |  | ||||||
|         } |  | ||||||
|         ProjectTempPath = tempPath; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,68 +0,0 @@ | |||||||
| using ImGuiNET; |  | ||||||
| 
 |  | ||||||
| namespace Nerfed.Editor.Project |  | ||||||
| { |  | ||||||
|     internal static class ProjectGui |  | ||||||
|     { |  | ||||||
|         private static string projectPath = string.Empty; |  | ||||||
|         private static string projectName = string.Empty; |  | ||||||
|         private static string projectFilePath = string.Empty; |  | ||||||
| 
 |  | ||||||
|         internal static void OnGui() |  | ||||||
|         { |  | ||||||
|             ImGui.Begin("Project"); |  | ||||||
|             ImGui.BeginGroup(); |  | ||||||
| 
 |  | ||||||
|             ImGui.InputText("Project Path", ref projectPath, 512); |  | ||||||
|             ImGui.InputText("Project Name", ref projectName, 512); |  | ||||||
| 
 |  | ||||||
|             string newProjectFilePath = Path.Combine(projectPath, ".project"); |  | ||||||
|             ImGui.Text(newProjectFilePath); |  | ||||||
| 
 |  | ||||||
|             if (ImGui.Button("Create Project")) |  | ||||||
|             { |  | ||||||
|                 EditorProject.Create(newProjectFilePath, projectName); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ImGui.EndGroup(); |  | ||||||
|             ImGui.BeginGroup(); |  | ||||||
| 
 |  | ||||||
|             ImGui.InputText("Project File Path", ref projectFilePath, 512); |  | ||||||
|             if (ImGui.Button("Open Project")) |  | ||||||
|             { |  | ||||||
|                 EditorProject.Open(projectFilePath); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ImGui.Text("Loaded project: "); |  | ||||||
|             if(EditorProject.Project != null) |  | ||||||
|             { |  | ||||||
|                 ImGui.Text(EditorProject.Project.Name); |  | ||||||
|                 ImGui.Text(EditorProject.ProjectFilePath); |  | ||||||
|                 ImGui.Text(EditorProject.ProjectSolutionFilePath); |  | ||||||
|                 ImGui.Text(EditorProject.ProjectPath); |  | ||||||
|                 ImGui.Text(EditorProject.ProjectContentPath); |  | ||||||
|                 ImGui.Text(EditorProject.ProjectTempPath); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 ImGui.Text("None"); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ImGui.EndGroup(); |  | ||||||
|             ImGui.BeginGroup(); |  | ||||||
| 
 |  | ||||||
|             if (ImGui.Button("Generate Solution")) |  | ||||||
|             { |  | ||||||
|                 EditorProject.GenerateSolution(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (ImGui.Button("Compile")) |  | ||||||
|             { |  | ||||||
|                 EditorProject.Compile(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             ImGui.EndGroup(); |  | ||||||
|             ImGui.End(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										91
									
								
								Nerfed.Runtime.Generator/HookSourceGenerator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								Nerfed.Runtime.Generator/HookSourceGenerator.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | using Microsoft.CodeAnalysis; | ||||||
|  | using Microsoft.CodeAnalysis.CSharp.Syntax; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | 
 | ||||||
|  | namespace Nerfed.Runtime.Generator | ||||||
|  | { | ||||||
|  |     [Generator] | ||||||
|  |     public class HookSourceGenerator : ISourceGenerator | ||||||
|  |     { | ||||||
|  |         public void Execute(GeneratorExecutionContext context) | ||||||
|  |         { | ||||||
|  |             // Ensure the syntax receiver is not null and is of the expected type | ||||||
|  |             if (context.SyntaxReceiver is not HookSyntaxReceiver syntaxReceiver) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             // Check if we have collected any hook methods | ||||||
|  |             List<MethodDeclarationSyntax> hookMethods = syntaxReceiver.HookMethods; | ||||||
|  |             if (hookMethods == null || !hookMethods.Any()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             StringBuilder codeBuilder = new StringBuilder(); | ||||||
|  | 
 | ||||||
|  |             codeBuilder.AppendLine("using System;"); | ||||||
|  |             codeBuilder.AppendLine(""); | ||||||
|  |             codeBuilder.AppendLine("namespace Nerfed.Runtime.Generator;"); | ||||||
|  |             codeBuilder.AppendLine(""); | ||||||
|  |             codeBuilder.AppendLine($"// Generated by {typeof(HookSourceGenerator)}"); | ||||||
|  |             codeBuilder.AppendLine("public static class Hook"); | ||||||
|  |             codeBuilder.AppendLine("{"); | ||||||
|  |             codeBuilder.AppendLine("    public static void InvokeHooks()"); | ||||||
|  |             codeBuilder.AppendLine("    {"); | ||||||
|  | 
 | ||||||
|  |             foreach (MethodDeclarationSyntax method in hookMethods) | ||||||
|  |             { | ||||||
|  |                 SemanticModel model = context.Compilation.GetSemanticModel(method.SyntaxTree); | ||||||
|  | 
 | ||||||
|  |                 if (model.GetDeclaredSymbol(method) is not IMethodSymbol methodSymbol) | ||||||
|  |                 { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (methodSymbol.DeclaredAccessibility != Accessibility.Public || !methodSymbol.IsStatic) | ||||||
|  |                 { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 codeBuilder.AppendLine($"        {methodSymbol.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}.{methodSymbol.Name}();"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             codeBuilder.AppendLine("    }"); | ||||||
|  |             codeBuilder.AppendLine("}"); | ||||||
|  | 
 | ||||||
|  |             // Add the generated code to the compilation | ||||||
|  |             context.AddSource("Hook.g.cs", codeBuilder.ToString()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         public void Initialize(GeneratorInitializationContext context) | ||||||
|  |         { | ||||||
|  |             context.RegisterForSyntaxNotifications(() => new HookSyntaxReceiver()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public class HookSyntaxReceiver : ISyntaxReceiver | ||||||
|  |         { | ||||||
|  |             public List<MethodDeclarationSyntax> HookMethods { get; } = new List<MethodDeclarationSyntax>(); | ||||||
|  | 
 | ||||||
|  |             public void OnVisitSyntaxNode(SyntaxNode syntaxNode) | ||||||
|  |             { | ||||||
|  |                 // Check if the node is a method declaration | ||||||
|  |                 if (syntaxNode is MethodDeclarationSyntax methodDeclaration) | ||||||
|  |                 { | ||||||
|  |                     // Ensure the method declaration has attribute lists | ||||||
|  |                     if (methodDeclaration.AttributeLists.Count == 0) | ||||||
|  |                         return; | ||||||
|  | 
 | ||||||
|  |                     // Check if the method has the Hook attribute | ||||||
|  |                     bool hasHookAttribute = methodDeclaration.AttributeLists | ||||||
|  |                         .SelectMany(attrList => attrList.Attributes) | ||||||
|  |                         .Any(attr => attr.Name.ToString() == "Hook"); | ||||||
|  | 
 | ||||||
|  |                     if (hasHookAttribute) | ||||||
|  |                     { | ||||||
|  |                         HookMethods.Add(methodDeclaration); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								Nerfed.Runtime.Generator/Nerfed.Runtime.Generator.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Nerfed.Runtime.Generator/Nerfed.Runtime.Generator.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  | 	<PropertyGroup> | ||||||
|  | 		<TargetFramework>netstandard2.0</TargetFramework> | ||||||
|  | 		<LangVersion>latest</LangVersion> | ||||||
|  | 		<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> | ||||||
|  | 		<Configurations>Debug;Test;Release</Configurations> | ||||||
|  | 		<Platforms>x64</Platforms> | ||||||
|  | 	</PropertyGroup> | ||||||
|  |  | ||||||
|  | 	<ItemGroup> | ||||||
|  | 	  <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4"> | ||||||
|  | 	    <PrivateAssets>all</PrivateAssets> | ||||||
|  | 	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||||
|  | 	  </PackageReference> | ||||||
|  | 	  <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.11.0"/> | ||||||
|  | 	</ItemGroup> | ||||||
|  |  | ||||||
|  | 	<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> | ||||||
|  | 		<DefineConstants>TRACE;LOG_INFO;PROFILING</DefineConstants> | ||||||
|  | 	</PropertyGroup> | ||||||
|  |  | ||||||
|  | 	<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Test|x64' "> | ||||||
|  | 		<DefineConstants>TRACE;LOG_ERROR;PROFILING</DefineConstants> | ||||||
|  | 		<Optimize>true</Optimize> | ||||||
|  | 	</PropertyGroup> | ||||||
|  |  | ||||||
|  | 	<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' "> | ||||||
|  | 		<DefineConstants>TRACE;LOG_ERROR</DefineConstants> | ||||||
|  | 		<Optimize>true</Optimize> | ||||||
|  | 	</PropertyGroup> | ||||||
|  | 	 | ||||||
|  | </Project> | ||||||
| @@ -72,6 +72,7 @@ public static class Engine | |||||||
|         AudioDevice = new AudioDevice(); |         AudioDevice = new AudioDevice(); | ||||||
| 
 | 
 | ||||||
|         OnInitialize?.Invoke(); |         OnInitialize?.Invoke(); | ||||||
|  |         Nerfed.Runtime.Generator.Hook.InvokeHooks(); | ||||||
| 
 | 
 | ||||||
|         while (!quit) |         while (!quit) | ||||||
|         { |         { | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								Nerfed.Runtime/Hook/HookAttribute.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Nerfed.Runtime/Hook/HookAttribute.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Nerfed.Runtime.Hook | ||||||
|  | { | ||||||
|  |     [AttributeUsage(AttributeTargets.Method, Inherited = false)] | ||||||
|  |     public class HookAttribute : Attribute | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								Nerfed.Runtime/Hook/HookTest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Nerfed.Runtime/Hook/HookTest.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | namespace Nerfed.Runtime.Hook | ||||||
|  | { | ||||||
|  |     public static class HookTest | ||||||
|  |     { | ||||||
|  |         [Hook] | ||||||
|  |         public static void Test() | ||||||
|  |         { | ||||||
|  |             Log.Info("Hook!"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -11,6 +11,7 @@ | |||||||
|         <IsPackable>false</IsPackable> |         <IsPackable>false</IsPackable> | ||||||
|         <Configurations>Debug;Test;Release</Configurations> |         <Configurations>Debug;Test;Release</Configurations> | ||||||
|         <Platforms>x64</Platforms> |         <Platforms>x64</Platforms> | ||||||
|  | 		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> | ||||||
|     </PropertyGroup> |     </PropertyGroup> | ||||||
|  |  | ||||||
|     <PropertyGroup> |     <PropertyGroup> | ||||||
| @@ -40,4 +41,10 @@ | |||||||
|         <Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs" /> |         <Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs" /> | ||||||
|     </ItemGroup> |     </ItemGroup> | ||||||
|      |      | ||||||
|  |     <ItemGroup> | ||||||
|  |       <ProjectReference Include="..\Nerfed.Runtime.Generator\Nerfed.Runtime.Generator.csproj" | ||||||
|  | 						OutputItemType="Analyzer" | ||||||
|  | 						ReferenceOutputAssembly="false" /> | ||||||
|  |     </ItemGroup> | ||||||
|  |      | ||||||
| </Project> | </Project> | ||||||
| @@ -14,6 +14,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Editor", "Nerfed.Edi | |||||||
| EndProject | EndProject | ||||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Compiler", "Nerfed.Compiler\Nerfed.Compiler.csproj", "{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Compiler", "Nerfed.Compiler\Nerfed.Compiler.csproj", "{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Runtime.Generator", "Nerfed.Runtime.Generator\Nerfed.Runtime.Generator.csproj", "{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|x64 = Debug|x64 | 		Debug|x64 = Debug|x64 | ||||||
| @@ -45,6 +47,12 @@ Global | |||||||
| 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Release|x64.Build.0 = Release|x64 | 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Release|x64.Build.0 = Release|x64 | ||||||
| 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.ActiveCfg = Test|x64 | 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.ActiveCfg = Test|x64 | ||||||
| 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.Build.0 = Test|x64 | 		{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.Build.0 = Test|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Debug|x64.ActiveCfg = Debug|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Debug|x64.Build.0 = Debug|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Release|x64.ActiveCfg = Release|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Release|x64.Build.0 = Release|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Test|x64.ActiveCfg = Test|x64 | ||||||
|  | 		{8743FDEF-4FF6-48F9-9F64-7BDEC543C105}.Test|x64.Build.0 = Test|x64 | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user